- 快速定位用户反馈的问题
- 运营可自定义追踪行为,方便研究
- 为产品定位做更多的参考
期待达到的效果
- 追踪代码和业务代码分离
- 抽离出来作为其他项目的Kit使用
- 根据后台动态下发的文件追踪相应的页面、事件,并根据设置确定日志上传时机
思路
1. 追踪页面轨迹
主要借助nav的api
记下push\popset\present\dismiss的日志
对于每个一vc用地址、className来标记,前者用来标记vc数组,后者用来匹配路径
对于有tab的app,记录下当前的tab页很重要。
我采用的方法是,hook住funname、funname记录下tabName或者tabIndex,后者只有在代码主动设置selectedIndex的才会调用,前者会在用户点击tabItem的时候响应。对于后者,我们可以取index做标记;对于前者,我们可以取itemName做标记,因此如果对追踪路径有要求,有两个方式。
- app端,对tabName和index做一个对照
- 后端配置时直接采用tabName||index的方式
2. 追踪点击事件
响应链
点击事件分:
- UIControl类点击事件
继承自UIControl的响应组件在响应到事件后,会将target、action转发给单例UIApplication,由UIApplication完成分发。
调用栈如下
- RunLoopRun…
- UIApplication sendEvent
- UIWindow sendEvent
- UIWindow sendTouchesForEvent
- UIControl…
- UIApplication sendAction:to:from:forEvent:
*objc_sendMsg
- UIApplication sendAction:to:from:forEvent:
- UIControl…
- UIWindow sendTouchesForEvent
- UIWindow sendEvent
- UIApplication sendEvent
因此,我们可以hook住UIApplication的sendAction:(SEL)action to:(nullable id)target from:(nullable id)sender forEvent:(nullable UIEvent *)event方法,记录点击空间、响应对象、以及消息,而不必对UIButton、UISwitch等组件分别hook。
对于实际项目,我们需要用户具体点击了哪个button、switch
在这里,我没有采用tag之类的标志,首先加tag需要改动太多的业务代码,而且加了tag之后,还另外需要一张对照表来记录关系。
系统自带的api可以满足我们的需求。
以UIButton为例,UI上,我们会给其设置图片或者标题,直接用这个来标记,日志的可读性更佳。
读取UIButton的标题不比赘述。
这里这里介绍一下如何用图片来标记UIButton。
UI控件有一个属性accessibilityIdentifier,习惯用storyboard的话,应该很熟悉这个属性。
我们可以利用这个属性,在hook出设置图片的api,直接用图片的名字来作为标记。
这样,我们对于一个button,可以用标题或者图片名来标记了,非常友好
UIGestureRecognizer 类响应的手势
对于这类事件,大多数人的做法是hook住该类的
init方法,然后再写一个target的分类,hook相应的方法。
此法可行,但是要给业务类写分类,我并不十分想这么干。。。。
于是我机智地查看了调用栈,- RunLoopRun…
- UIApplication sendEvent
- UIWindow sendEvent
- UIGestureEnvironment _deliverEvent: toGestureRecognizers:usingBlock:
- UIGestureRecognizer _updateGesture…
- UIGestureRecognizerTarget _sendActionWithGestureRecognizer:
*objc_sendMsg
- UIGestureRecognizerTarget _sendActionWithGestureRecognizer:
- UIGestureRecognizer _updateGesture…
- UIGestureEnvironment _deliverEvent: toGestureRecognizers:usingBlock:
- UIWindow sendEvent
很明显,~~~~
但是悲剧地发现 UIGestureRecognizerTarget是一个私有类
难道这就是结束了吗?并不是。
其实我们的诉求还是需要知道sender、target、 至于是在哪个VC内的控件,我们可以通过路径轨迹得知,不必纠结于此。
- tableView 等点击事件
要hooktableView的delegate、以及delegate相应的sel方法。
也就是要给业务类写分类了。。我并不十分想这么干。。。。
然而除此以外,
我没有想出特别好的办法。卒。
3. 日志
日志记录格式:
时间– 路径名-
响应视图(视图标志)
响应视图(视图标志)
响应视图(视图标志)
…..
时间– 路径名-
响应视图(视图标志)
响应视图(视图标志)
响应视图(视图标志)
…..
实时写入本地的txt文件中
上传策略由配置文件来决定
4.
5. improve
tableView等cell上的点击事件我还要继续找寻更好的方法
ps.虽然现在用户真的很少,有些东西可研究可不研究,可做可不做,但是想到了不去做,就是觉得todo list越来越长很想去完成啊
源码可以在我的github上,Pie这个项目里找到【不一定更新了】