要作數據分析不外乎就兩種,一種服務器經過接口調用狀況統計,另一種就是前端埋點統計,固然前端埋點統計能夠更精準的統計更多數據信息~html
大體分爲三種,代碼埋點、可視化埋點,無埋點前端
很簡單明瞭就是在須要統計埋點的控制器和按鈕事件等地方作好埋點處理git
根據標識來識別每個事件, 針對指定的事件進行取參埋點。而事件的標識與參數信息都寫在配置表中,經過動態下發配置表來實現埋點統計github
無埋點是指開發人員集成採集 SDK 後,SDK 便直接開始捕捉和監測用戶在應用裏的全部行爲,並所有上報,不須要開發人員添加額外代碼json
想關於這三種的介紹,網上資料一大堆,感興趣的朋友能夠本身去搜索看看,安全
美團點評前端無痕埋點實踐服務器
下面是一個很簡單的統計用戶瀏覽埋點方式,其實就是利用Runtime交換viewDidLoad
方法markdown
+ (void)load{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
kMethodSwizzling(self.class, @selector(viewDidLoad), @selector(kj_viewDidLoad));
});
}
- (void)kj_viewDidLoad{
[self kj_viewDidLoad];
NSString *clazz = NSStringFromClass([self class]);
NSDictionary *dict = @{
@"userid":KJHookInfo.shared.userid,
@"viewController":clazz
};
NSString *parameter = dict.jsonString.kj_aesEncryptKey(@"key");
//TODO:上傳數據
}
複製代碼
升級一下,瀏覽指定控制器埋點,經過接口動態返回須要統計的界面控制器,儲存在hookViewControllers
,而後統計網絡
- (void)kj_viewDidLoad{
[self kj_viewDidLoad];
NSString *clazz = NSStringFromClass([self class]);
BOOL isHook = ({
BOOL isHook = NO;
for (NSString *name in KJHookInfo.shared.hookViewControllers) {
if ([name isEqualToString:clazz]) {
isHook = YES;
break;
}
}
isHook;
});
if (isHook) {
NSDictionary *dict = @{
@"userid":KJHookInfo.shared.userid,
@"viewController":clazz
};
NSString *parameter = dict.jsonString.kj_aesEncryptKey(@"key");
//TODO:上傳數據
}
}
複製代碼
再介紹一個統計頁面停留時長的埋點處理 簡單講就是交換viewWillAppear:
和viewDidDisappear:
app
+ (void)load{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
kMethodSwizzling(self.class, @selector(viewWillAppear:), @selector(kj_viewWillAppear:));
kMethodSwizzling(self.class, @selector(viewDidDisappear:), @selector(kj_viewDidDisappear:));
});
}
- (void)kj_viewWillAppear:(BOOL)animated{
[self kj_viewWillAppear: animated];
// 記錄進入時間
KJHookInfo.shared.time = CFAbsoluteTimeGetCurrent();
}
- (void)kj_viewDidDisappear:(BOOL)animated{
[self kj_viewDidDisappear: animated];
NSString *clazz = NSStringFromClass([self class]);
BOOL isHook = ({
BOOL isHook = NO;
for (NSString *name in KJHookInfo.shared.hookViewControllers) {
if ([name isEqualToString:clazz]) {
isHook = YES;
break;
}
}
isHook;
});
if (isHook) {
NSTimeInterval time = CFAbsoluteTimeGetCurrent() - KJHookInfo.shared.time;
NSDictionary *dict = @{
@"userid":KJHookInfo.shared.userid,
@"time":time,
@"viewController":clazz
};
NSString *parameter = dict.jsonString.kj_aesEncryptKey(@"key");
//TODO:上傳數據
}
}
複製代碼
大多數可點擊UI控件都是基於UIControl,核心仍是交互方法sendAction:to:forEvent:
,下面提供一種統計到某個具體頁面的按鈕
@implementation UIControl (KJHook)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
kMethodSwizzling(self.class, @selector(sendAction:to:forEvent:), @selector(kj_sendAction:to:forEvent:));
});
}
- (void)kj_sendAction:(SEL)action to:(nullable id)target forEvent:(nullable UIEvent *)event {
[self kj_sendAction:action to:target forEvent:event];
_weakself;
kGCD_async(^{
if ([NSStringFromClass(weakself.class) isEqualToString:@"UIButton"]) {
void (^kDealButton)(NSString *) = ^(NSString *clazz){
NSDictionary *dict = @{
@"userid":@"userid",
@"centerX":[NSString stringWithFormat:@"%.2f",weakself.centerX],
@"centerY":[NSString stringWithFormat:@"%.2f",weakself.centerY],
@"viewController":clazz
};
NSString *parameter = dict.jsonString.kj_aesEncryptKey(@"key");
NSLog(@"%@",parameter);
//TODO:上傳數據
};
kGCD_main(^{
kDealButton(NSStringFromClass([[target viewController] class]));
});
}
});
}
@end
複製代碼
這裏若是想更準確,還可給每一個按鈕編tag值,固然這個工程量就比較大,這邊只是提供思路,具體怎麼作示實際狀況爲準
這裏值得一提的就是,在交換方法的時候,必定要全局查詢是否命名衝突(有沒有方法名重複),不然可能會出現你埋點的方法壓根不執行,原理能夠參考我另一篇關於Category介紹的文章iOS Category類別的使用及工具封裝
一般咱們埋好點以後,採起的方式都是調用服務器的一個指定接口,可是有一個缺陷就是在高峯期時刻訪問量會很是巨大,就有超出服務器範圍的可能
先來介紹網址連接的構成,https://upload-images.jianshu.io/upload_images/1933747-82138031f05852ab.gif?tR8XBkv3BaBjjEeck9VbeiZauP73MdXWlhvmUq+BAFY=
scheme:https
host:upload-images.jianshu.io
path:/upload_images/1933747-82138031f05852ab.gif
query:tR8XBkv3BaBjjEeck9VbeiZauP73MdXWlhvmUq+BAFY=
複製代碼
正常咱們訪問一張圖片,其實只須要scheme://
+ host
+ path
三部分就能夠正常訪問
可是下面這張格式組成 scheme://
+ host
+ path
+ ?
+ query
也是能夠正常訪問
因此咱們能夠將埋點信息放在query
當中,而後只須要統計這張圖片的訪問記錄就能夠簡單快捷的拿到埋點的內容
1像素
的圖片,這樣也不會怎麼佔用服務器的帶寬NSDictionary *dict = @{@"app":@"appname"};
NSString *parameter = dict.jsonString.kj_aesEncryptKey(@"key");
複製代碼
一樣也是能夠訪問到圖片地址 https://upload-images.jianshu.io/upload_images/1933747-82138031f05852ab.gif?tR8XBkv3BaBjjEeck9VbeiZauP73MdXWlhvmUq+BAFY=
咱們都知道訪問獲得的圖片都是data數據,那麼咱們是否也能夠把咱們想要反饋給客戶端的數據藏於data當中解析呢?
那麼你們還有什麼比較優秀的埋點方式呢?歡迎分享,謝謝~
pod 'KJEmitterView'
引入便可