埋點(diǎn)的重要性
- 提高增長率:精準(zhǔn)營銷分析赋朦,優(yōu)化推廣效果屯曹,改進(jìn)落地頁浪讳,提升轉(zhuǎn)化率
- 提升用戶活躍度:更細(xì)分的自定義活躍與留存分析透揣,全面提升用戶活躍度
- 精準(zhǔn)運(yùn)營:用戶分群楔脯,用戶畫像,多維交叉分析,實(shí)現(xiàn)精準(zhǔn)運(yùn)營
- 優(yōu)化產(chǎn)品體驗(yàn):通過行為分析塔插,事件分析糜烹,漏斗分析,優(yōu)化產(chǎn)品體驗(yàn)
常見的埋點(diǎn)方式
1. 代碼埋點(diǎn)
通過手寫代碼的方式進(jìn)行埋點(diǎn)。代碼埋點(diǎn)存在高度耦合薪前、依賴發(fā)版鳍侣、無法動態(tài)更新惨驶、容易誤刪、重復(fù)埋點(diǎn)等問題百匆。
2. 無埋點(diǎn)
無埋點(diǎn)方式主要是指不需要代碼埋點(diǎn),通過app端上報控件信息給埋點(diǎn)配置服務(wù)器洒扎,數(shù)據(jù)人員通過上報數(shù)據(jù)進(jìn)行配置埋點(diǎn)信息淌友,然后再下發(fā)給app端拨拓,實(shí)現(xiàn)無需添加代碼奥务、動態(tài)配置收集用戶使用app的所有事件。
無埋點(diǎn)實(shí)現(xiàn)方式
iOS 無埋點(diǎn)方案主要依靠AOP(Aspect Oriented Programming)面向切片編程,通過預(yù)編譯方式和運(yùn)行期動態(tài)代理針對業(yè)務(wù)處理過程的實(shí)體及其屬性和行為進(jìn)行抽象封裝炕置,以獲得更加清晰高效的邏輯單元劃分。
iOS實(shí)現(xiàn)AOP編程况既,主要依賴iOS的runtime機(jī)制,method swizzling方法,method swizzling本質(zhì)上就是對IMP(一個函數(shù)指針胳徽,保存了方法的地址)和SEL(類成員方法的指針匙瘪,但不同于C語言中的函數(shù)指針,函數(shù)指針直接保存了方法的地址涧卵,但SEL只是方法編號)進(jìn)行交換。
method swizzling是發(fā)生在運(yùn)行時的胎撤,主要用于在運(yùn)行時將兩個method進(jìn)行交換,我們可以將method swizzling代碼寫到任何地方巫俺,但是只有在這段method swizzling碼執(zhí)行完畢之后互換才起作用介汹。
method swizzling原理
在Objective-C中調(diào)用一個方法,其實(shí)是向一個對象發(fā)送消息嘹承,查找消息的唯一依據(jù)是selector的名字叹卷。利用Objective-C的動態(tài)特性坪它,可以實(shí)現(xiàn)在運(yùn)行時偷換selector對應(yīng)的方法實(shí)現(xiàn)往毡,達(dá)到給方法掛鉤的目的开瞭。每個類都有一個方法列表嗤详,存放著selector的名字和方法實(shí)現(xiàn)的映射關(guān)系葱色。IMP有點(diǎn)類似函數(shù)指針冬筒,指向具體的Method實(shí)現(xiàn)茅主。
利用method_exchangeImplementations响牛、class_replaceMethod赫段、method_setImplementation等方法偷換selector的IMP糯笙。
例:
#import <UIKit/UIKit.h>
@interface UIViewController (DDTracker)
@end
#import "UIViewController+DDTracker.h"
#import <objc/runtime.h>
@implementation UIViewController (DDTracker)
+ (void)load {
Method originalSelector = class_getInstanceMethod(self, @selector(viewWillAppear:));
Method swizzledSelector = class_getInstanceMethod(self, @selector(swiz_viewWillAppear:));
method_exchangeImplementations(originalSelector, swizzledSelector);
}
- (void)swiz_viewWillAppear:(BOOL)animated
{
//在這里填寫需要插入的代碼
[self sendTrackerData];
//執(zhí)行原來的代碼豺憔,不影響代碼邏輯
[self swiz_viewWillAppear:animated];
}
- (void)sendTrackerData {
}
iOS常用UI控件
UIControl
UIControl是UIView的子類恭应,當(dāng)然也是UIResponder的子類昼榛。UIControl是諸如UIButton剔难、UISwitch、UITextField等控件的父類衫嵌,通過endTrackingWithTouch:withEvent:方法可以監(jiān)控UIControl的觸摸事件彻秆。
UITableView
UITableView是iOS主要列表控件,通過UITableViewDelegate的tableView:didSelectRowAtIndexPath:方法可以監(jiān)控到UITableView的點(diǎn)擊事件酒朵。
UICollectionView
UICollectionView 這個類是iOS6 引進(jìn)的API蔫耽,它的布局更加靈活匙铡,簡單來說就是多列的UITableView,UICollectionView的實(shí)現(xiàn)和UITableView的實(shí)現(xiàn)基本一樣碍粥,也是存在datasource和delegate的嚼摩,通過UICollectionViewDelegate的collectionView:didSelectItemAtIndexPath:方法可以監(jiān)控到UICollectionView的點(diǎn)擊事件枕面。
UIView
iOS中UIView添加UITapGestureRecognizer手勢實(shí)現(xiàn)點(diǎn)擊效果潮秘,通過UITapGestureRecognizer的initWithTarget:action:方法可以監(jiān)控到UIView的點(diǎn)擊事件。
事件ID
事件ID的組成主要是通過Viewcontroller(或TableCell)稠通、Class和action通過一定規(guī)則拼接組成滋尉。
上報控件信息
當(dāng)用戶點(diǎn)擊控件時玉控,通過runtime運(yùn)行時在執(zhí)行響應(yīng)方法后,調(diào)用接口狮惜,將控件ID以及當(dāng)前class中綁定的數(shù)據(jù)取出來傳給服務(wù)器高诺。
配置信息下拉
[
{
"DD_TRACKER_EVENTID_KEY":"DDButtonViewController&&trackerButtonClick:"
},
{
"DD_TRACKER_EVENTID_KEY":"DDTableViewController&&tableView:didSelectRowAtIndexPath:"
},
{
"DD_TRACKER_EVENTID_KEY":"DDCollectionViewController&&collectionView:didSelectItemAtIndexPath:"
},
{
"DD_TRACKER_EVENTID_KEY":"DDGestureViewController&&gestureLabelClick:"
}
]
上報埋點(diǎn)事件
通過校驗(yàn)配置信息中的“ DD_TRACKER_EVENTID_KEY”字段來判斷是否發(fā)送打點(diǎn)信息碌识。
使用方法
#import "DDAppDelegate.h"
@implementation DDAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
//開啟打點(diǎn)
[[DDAutoTrackerManager sharedInstance] startWithCompletionBlockWithSuccess:^(NSDictionary *trackerDictionary) {
//成功打點(diǎn)回調(diào)
} debug:^(NSDictionary *trackerDictionary) {
//調(diào)試模式回調(diào)
}];
//開啟調(diào)試模式
[DDAutoTrackerManager sharedInstance].isDebug = YES;
//讀取本地配置文件
NSString * filePath = [[NSBundle mainBundle] pathForResource:@"tracker" ofType:@"json"];
NSData * jsonData = [NSData dataWithContentsOfFile:filePath];
if (jsonData) {
NSError *error;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:jsonData options: NSJSONReadingMutableContainers error: &error];
if (nil == error &&
jsonArray) {
[DDAutoTrackerManager sharedInstance].configArray = jsonArray;
}
}
return YES;
}
@end
注:建議將"DDAutoTracker.h"引用放在".pch"文件中
數(shù)據(jù)綁定
大多數(shù)情況下,需要綁定一些控件信息虱而。建議使用服務(wù)端返回的數(shù)據(jù)為準(zhǔn)筏餐。調(diào)用“configInfoData:”方法配置需要上報的數(shù)據(jù),例:
#import "DDViewController.h"
@interface DDViewController ()
@end
@implementation DDViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
//配置打點(diǎn)info信息
[self configInfoData:@{@"id":@"your id",
@"type":@"your type"}];
}
@end
結(jié)語
通過無埋點(diǎn)方式完成數(shù)據(jù)統(tǒng)計牡拇,增加了開發(fā)效率魁瞪,并保證了數(shù)據(jù)分析的準(zhǔn)確性。Github地址惠呼,如果您覺得對您有幫助剔蹋,請點(diǎn)“star”,謝謝凯沪!