1、可视化无痕埋点:
简介:不需要代码埋点,通过可视化界面圈选埋点范围,通过自定义脚本语言抓取业务字段生成埋点的方案
目的:为解决普通埋点与业务代码耦合,漏埋错埋问题
内容:包含线下圈选埋点SDK、线上用户埋点SDK,WEB管理平台,埋点后台
技术点:ui事件的拦截,控件唯一id,业务字段抓取规则解析,埋点的存储上传,配置文件的版本控制等
2、示例:产品购买按钮埋点步骤
(1)线下开启APP圈选功能,点击购买按钮,生成一条埋点配置信息,并与安卓端匹配;
(2)web配置平台编辑配置该信息,添加附加字段抓取规则;
(3)线上app启动时服务器下发对应版本的埋点配置文件,用户点击该按钮时拦截UI事件,根据生成唯一id在配置文件中做匹配;
(4)获取该按钮的配置文件中的业务字段规则,在当前环境下抓取数据,生成埋点存储上传;
3、事件拦截:runtime的方法交换做事件拦截
页面:拦截willappear和disappear,注意进前台后台crash等引起的不匹配,时间戳校正
事件分为button点击cell点击手势点击等,拦截要获取到三个元素:控件,target,action
Button:拦截UIControl的sendAction:to:forEvent
Cell:
1、拦截UITableView的setDelegate:获取delegate对象
2、再拦截delegate的didSelectRowAtIndexPath:方法获取cell
Gesture:
1、拦截UIGestureRecognizer的addtarget:action:和initWithTarget:action:方法得到target和action;
2、拦截target的action:根据action的参数gesture.view获取控件;
3、若action无参,先动态添加一个有参的action:与原方法互换,当用户点击时会调用有参的action:再执行步骤2
实现方案2:NSProxy做消息转发
1、拦截UITableView的setDelegate:获取到delegate对象
2、创建一个NSProxy对象作为delegate对象的代理对象
3、在NSProxy对象中做消息转发,针对tableView:didSelectRowAtIndexPath:方法插入埋点代码
4、控件唯一id规则:
唯一ID规则:当前响应View的ViewPath(只有最后一层携带子view的index,其他均为类名)$事件的target类名$事件的SEL名称$tag值
示例:vc/view[0]/view[0]/button#target#selector#tag
AQJHomeVC/UIImageView/UIView[1]/UIButton#AQJHomeVC#clickShareAction#3
服务器下发的配置文件,嵌套字典
{
"HomeViewController":{
"控件id的MD5":{
"em附加字段抓取规则":[
{
"fn附加字段key":"userId",
"fnEl附加抓取规则":"userDefault.userId"
},{
"fn":"pId",
"fnEl":"selfVC.viewModel.pModel.pId"
}
]
}
},
“MyViewController”:{},
}
5、附加字段:
埋点携带的信息分为三类:不可变通用信息,可变通用信息,特定业务信息
不可变通用信息(设备信息、版本信息等)APP启动时上传一次
可变通用信息(用户登录id、当前网络状况、发生时间)埋点发生时获取
特定业务信息(点击购买按钮时保险id等)根据附加字段抓取规则在当前环境获取
从配置文件中匹配到抓取规则如:selfVC.viewModel.pModel.pId
先分割字符串,根据响应链获取控件所在VC,通过KVC获取属性值
附加字段抓取规则解析
获取附加字段:字段抓取规则 +上下文环境 + 规则解析算法
规则示例:
userDefault.userId
selfVC.viewModel.productList[indexPath.row].pModel.pId
事件拦截时能够得到的环境上下文:
点击的控件、控件所在VC、存储app信息的各种单利、(当前点击cell的indexPath)
规则元素&上下文变量映射
self 控件本身
selfVC 控件所在控制器
indexPath 点击的cell所在位置
userDefault 用户信息单利
client 手机设备信息单利
解析算法:
案例1:selfVC.viewModel.title,直接通过KVC获取
案例2:selfVC.viewModel.productList[indexPath.row].pModel.pId,先解析[]得到数值,取数组中的model,KVC获取pId
案例3:selfVC.viewModel.productList[(indexPath.row+2)*3+5].pModel.pId
使用队列将(indexPath.row +2)*3+5转换成中缀表达式(4+2)*3+5,转成后缀表达式,计算表达式结果,按方案2取值
6、圈选SDK:
打开圈选模式,遍历页面中可点击控件,画边框标注
选择要圈选的控件,填写备注信息,与安卓端进行匹配,生成一条埋点配置文件
7、埋点存储上传:
采用SQLite存储+GCD同步队列
埋点产生后先入库后根据策略上传
表结构:埋点数据转成二进制data,主键自增id;分为正常数据埋点和时时数据埋点两张表,表的插入读取删除使用同步列队
上传时机分为重要埋点实时上传、普通埋点满30条上传、APP启动、前后台切换超过30秒上传,上传成功之后删除表中数据
8、配置文件版本管理:
按APP版本号管理埋点配置信息
每次APP更新版本,后端需要从旧版本复制一份配置文件到新版本
APP提供失效埋点检测功能,可重新圈选来更正变更埋点信息
新增功能进行埋点圈选
9、不足之处:
附加字段不支持复杂规则、业务字段规则需了解代码、用户SDK使用了事件拦截和算法费性能