最近項目里要加入按鈕的點擊事件的統(tǒng)計和按鈕是否可點擊的權(quán)限控制,老大說了,不要第三方的埋點統(tǒng)計,要自己實現(xiàn),好吧,那就自己實現(xiàn)吧!
到底怎樣實現(xiàn),才最好呢!第一個想到的就是hook點擊事件,哎,runtime就是這么強大,想了想,確實很簡單,先說下我的思路。首先這個肯定有后臺的配合,移動端把所有的按鈕及頁面進(jìn)行編碼,再就是由后臺返回每個按鈕是否可點擊,如{"B0001P0001":"1"},表示B0001P0001編號的按鈕可點擊。好了,接下來說說我們iOS端是如何實現(xiàn)的吧,不多說了直接上代碼
#import <UIKit/UIKit.h>
@interface UIButton (myTM)
@property (nonatomic,copy)NSString *pageNo;
@end
#import "UIButton+myTM.h"
#import <objc/runtime.h>
static NSString *namekey = @"name";
@implementation UIButton (myTM)
- (void)setPageNo:(NSString *)pageNo {
objc_setAssociatedObject(self, &namekey, pageNo, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)pageNo {
return objc_getAssociatedObject(self, &namekey);
}
@end
按上述代碼建立一個UIButton的分類,給分類接一個pageNo屬性,這樣我們就可以根據(jù)pageNo知道對應(yīng)的按鈕是否可點擊了,在上代碼
#import <UIKit/UIKit.h>
@interface UIControl (runtime)
@end
#import "UIControl+runtime.h"
#import <objc/runtime.h>
#import "UIButton+myTM.h"
@implementation UIControl (runtime)
+(void)load {
Method m1 = class_getInstanceMethod(self, @selector(sendAction:to:forEvent:));
Method m2 = class_getInstanceMethod(self, @selector(mySendAction:to:forEvent:));
method_exchangeImplementations(m1, m2);
}
- (void)mySendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event {
if ([self isKindOfClass:[UIButton class]]) {
UIButton *b = (UIButton *)self;
//這里簡寫了,實際上肯定要根據(jù)拿到的pageNo作為key去取對應(yīng)的value,就可以得到對應(yīng)的按鈕是否可點擊了
if ([b.pageNo isEqualToString:@"1"]||!b.pageNo) {
[self mySendAction:action to:target forEvent:event];
//這里還可以加入按鈕點擊統(tǒng)計事件,這里我就不寫了
} else {
NSLog(@"該按鈕不可點擊");
return;
}
} else {
[self mySendAction:action to:target forEvent:event];
}
}
@end
這樣就算基本完成的,剩下就是測試代碼了
#import "ViewController.h"
#import "UIButton+myTM.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *image = [[UIButton alloc]initWithFrame:CGRectMake(50, 50, 50, 50)];
[self.view addSubview:image];
image.pageNo = @"1";
[image setBackgroundColor:[UIColor redColor]];
[image addTarget:self action:@selector(add:) forControlEvents:UIControlEventTouchUpInside];
UIButton *image2 = [[UIButton alloc]initWithFrame:CGRectMake(50, 150, 50, 50)];
[self.view addSubview:image2];
image2.pageNo = @"2";
[image2 setBackgroundColor:[UIColor blueColor]];
[image2 addTarget:self action:@selector(add:) forControlEvents:UIControlEventTouchUpInside];
UIButton *image3 = [[UIButton alloc]initWithFrame:CGRectMake(50, 250, 50, 50)];
[self.view addSubview:image3];
[image3 setBackgroundColor:[UIColor blackColor]];
[image3 addTarget:self action:@selector(add:) forControlEvents:UIControlEventTouchUpInside];
}
-(void)add:(UIButton *)btn{
NSLog(@"該按鈕可點擊");
}
好了,這就算完成了
這里是demo的gitHub地址:https://github.com/lzkevin1234/runtimeToCountAllAction