1. 埋点方案
代码埋点
由人员在触发事件的具体方法里,你就成为你自己的 “虚拟专用网络” 供应商。许多流行的 “虚拟专用网络” 服务已支持0penVPN,添加多行代码把需要上传的参数上报至服务端。
可视化埋点
根据标识来识别每一个事件,所以当你可以掌控自己的网络时, 针对指定的事件进行取参埋点。而事件的标识与参数信息都写在配置表中,为什么还要将你的网络连接绑定到特定的提供商呢?本系列中的第一篇展示了如何安装和配置一台作为你的 0penVPN 服务器的 Linux 计算机。,通过动态下发配置表来实现埋点统计。
无埋点
无埋点并不是不需要埋点,第二篇演示了如何安装和配置 0penVPN 服务器软件。这第三篇文章演示了如何在认证成功的情况下启动 0penVPN。要设置一个 0penVPN 服务器,更准确的说应该是“全埋”,你必须:◈ 创建一个配置文件。◈ 使用 设置 以启用路由。◈ 为所有的配置和认证文件设置适当的所有权, 前端的任意一个事件都定一个标识,以便使用非 root 账户运行 0penVPN 服务器守护程序。◈ 设置 0penVPN 加载适当的配置文件启动。◈ 配置你的防火墙。配置文件你必须在 中创建一个服务器配置文件。如果你想的话,所有的事件都别记录下来。通过定期上传记录文件,你可以从头开始,配合文件解析,0penVPN 包括了几个配置示例示例文件,解析出来我们想要的数据,可以以此作为开始。看看 就知道了。如果你想手工建立一个配置文件, 并生成可视化报告 ,可以从 或 开始(视情况而定), 因此实现“无埋点”统计。
2. 方案选择
通常业务都需要加埋点统计事件,但在每个业务类里埋点会导致每个页面内耦合了量的无关业务的埋点代码使得代码不够整洁,所以放弃了代码埋点。
考虑到无埋点成本较高,后期解析也复杂,选择了可视化埋点,即通过配置事件唯一标识,设置需要埋点分析的业务。
2.1 实现可视化埋点核心问题
封装埋点组件,降低耦合
如何实现后台配置唯一标识
埋点上报
2.2 针对第一个问题想到的方案如下:
每个业务页面添加一个埋点类,单独将埋点的方法提取到这个类中。
利用 在底层进行方法拦截,从而添加埋点代码。
结合AOP的核心思想:将应用程序中的业务逻辑同对其提供支持的通用服务进行分离,最后采用了第2种方案。
2.3 配置唯一标识问题
唯一标识的组成方式主要是又 来确定, 即任何一个事件都存在一个 与 。在此引入 AOP 编程, 即面向切面编程的思想,基于 的 能力,来 相应的方法,从而在 方法中进行统一的埋点处理。例如所有的按钮被点击时,都会触发 的 方法,我们 这个方法,即可拦截所有按钮的点击事件。
2.3.1 唯一标识(viewPath)的获取:
整个 APP 的视图结构可以看成是一颗树(),树的根节点就是 ,树的枝干由 及 组成,树的叶节点都是由 组成。
那么在 中用什么信息来表示其中任意一个 的位置呢?很容易想到的就是使用目标 到根之间的每个节点的深度(层次)组成一个路径,而节点的深度(层次)是指此节点在父节点中的 。这样确实能够唯一的表示此 了,但是有一个缺点:它的可读性很差。因此在此基础上又增加了每个节点的名称,节点的名称由当前节点的 的类名来表示。同时在开头都添加了一个页面名称作为标识。
因此,在 中,由一个 到根节点之间的每个节点的名称与深度(层次)共同组成的信息构成了此 的 。另外,由于在做 view 的统计分析时,都是以页面为单位的,因此 在生成 时,只到 view 所在的 级别,而非根的 。这样做也在一定程度上减少了 的长度。
和 的树级关系没有到每个具体的 ,避免产生很多无用的 ,而是将 作为描述信息传入。实现逻辑如下图:
2.3.4 唯一标识的作用主要分为两个分
事件的锁定
事件的锁定主要是靠 “事件唯一标识符”来锁定,而事件的唯一标识是由我们写入配置表中的。
埋点数据的上报。
埋点数据的数据又分为两种类型:固定数据与可变的业务数据, 而固定数据我们可以直接写到配置表中, 通过唯一标识来获取。而对于业务数据,数据是有持有者的, 例如我们 的一个属性值, 或者数据在 的某一个层级。就可以通过 的的方式来递归获取该属性的值来取到业务数据。
2.4 埋点上报
自定义埋点上报数据类型,上报到 ,后台进行数据分析
3. 实现分
3.1 SDK 架构3.2 技术原理3.2.1 Method-Swizzling
中的方法调用其实是向一个对象发送消息 ,利用 的动态性可以实现方法的交换。
用 方法来交换两个方法中的IMP
用 方法来替换类的方法,
用 方法来直接设置某个方法的
3.2.2 Target-Action
按钮的点击事件, 会调用 来将行为消息转发到 ,再由 调用其 方法来将消息分发到指定的 上。
3.3 分析及实现
3.3.1 需要添加埋点统计的地方
相关的点击事件
页面进入、页面推出
的点击
的点击
手势相关事件
3.3.2 分析
对于用户交互的操作,我们使用 对应的方法 下 便可以得到进行的交互操作。这个方法对 及继承 的子类对象有效,如:、 等。
对于 , 下 这个方法知道哪个页面显示了就足够了。
对于 及 ,我们 方法。检测其有没有实现对应的点击代理,因为 及 是 的不是必须要实现的。
对于手势,我们在创建的时候进行 ,方法为 。
3.3.3 实现原理
用运行时方法替换方法实现无侵入的埋点方法。
实现原理图:
具体实现方法:
创建一个运行时方法替换类 ,实现替换的方法 `swizzingForClass: originalSel: swizzingSel:``
这个方法利用运行时 进行交换,当原方法被调用时,就会 到指定的新方法去执行。
3.3.4 埋点分类实现1. UIViewController+Track(页面进入、页面推出)
在 方法里使用了 进行方法替换,在替换的方法里执行需要埋点的方法 实现埋点。这样每个 生命周期到了 都会执行埋点的方法。
在这里,我们是通过类名 来区分不同的控制器的。
2. UIControl+Track(button相关的点击事件)
找到点击事件的方法 ,然后在 方法里使用 替换新的方法。
和 生命周期埋点不同的是,一个类中可能有许多不同的 子类,相同的 子类在不同的视图中的埋点也要区分出来,所以我们通过 来区别,即类名加方法名的格式作为唯一标识。
、、手势的点击事件与上述实现方法类似。
3.3.5 埋点配置文件
埋点配置文件通过唯一标识锁定事件,可以使用 文件或 文件, 里就随便写了一些测试数据, 是直接放在了项目资源里,实际项目是通过 从服务器下载的配置文件,以实现实时更新埋点配置。
测试 文件:
总结
使用运行时方法的替换实现了无侵入埋点,但仍存在很多问题,比如唯一标识难以维护、准确性有待验证。目前的方式只能实现页面进、出以及点击事件的埋点统计,涉及到具体业务的埋点统计,比如开机启动、需要上报参数信息等类型的埋点还是要依赖代码埋点。所以无侵入埋点方案还有很优化空间。
附 Demo :
-End-
免责声明:文中图片均来源于网络,如有版权问题请联系我们进行删除!