iOS开发高手课
戴铭
前滴滴出行技术专家
立即订阅
11464 人已学习
课程目录
已完结 46 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 锚定一个点,然后在这个点上深耕
免费
基础篇 (20讲)
01 | 建立你自己的iOS开发知识体系
02 | App 启动速度怎么做优化与监控?
03 | Auto Layout 是怎么进行自动布局的,性能如何?
04 | 项目大了人员多了,架构怎么设计更合理?
05 | 链接器:符号是怎么绑定到地址上的?
06 | App 如何通过注入动态库的方式实现极速编译调试?
07 | Clang、Infer 和 OCLint ,我们应该使用谁来做静态分析?
08 | 如何利用 Clang 为 App 提质?
09 | 无侵入的埋点方案如何实现?
10 | 包大小:如何从资源和代码层面实现全方位瘦身?
11 | 热点问题答疑(一):基础模块问题答疑
12 | iOS 崩溃千奇百怪,如何全面监控?
13 | 如何利用 RunLoop 原理去监控卡顿?
14 | 临近 OOM,如何获取详细内存分配信息,分析内存问题?
15 | 日志监控:怎样获取 App 中的全量日志?
16 | 性能监控:衡量 App 质量的那把尺
17 | 远超你想象的多线程的那些坑
18 | 怎么减少 App 电量消耗?
19 | 热点问题答疑(二):基础模块问题答疑
20 | iOS开发的最佳学习路径是什么?
应用开发篇 (12讲)
21 | 除了 Cocoa,iOS还可以用哪些 GUI 框架开发?
22 | 细说 iOS 响应式框架变迁,哪些思想可以为我所用?
23 | 如何构造酷炫的物理效果和过场动画效果?
24 | A/B 测试:验证决策效果的利器
25 | 怎样构建底层的发布和订阅事件总线?
26 | 如何提高 JSON 解析的性能?
27 | 如何用 Flexbox 思路开发?跟自动布局比,Flexbox 好在哪?
28 | 怎么应对各种富文本表现需求?
29 | 如何在 iOS 中进行面向测试驱动开发和面向行为驱动开发?
30 | 如何制定一套适合自己团队的 iOS 编码规范?
31 | iOS 开发学习资料和书单推荐
32 | 热点问题答疑(三)
原理篇 (6讲)
33 | iOS 系统内核 XNU:App 如何加载?
34 | iOS 黑魔法 Runtime Method Swizzling 背后的原理
35 | libffi:动态调用和定义 C 函数
36 | iOS 是怎么管理内存的?
37 | 如何编写 Clang 插件?
38 | 热点问题答疑(四)
原生与前端共舞 (5讲)
39 | 打通前端与原生的桥梁:JavaScriptCore 能干哪些事情?
40 | React Native、Flutter 等,这些跨端方案怎么选?
41 | 原生布局转到前端布局,开发思路有哪些转变?
42 | iOS原生、大前端和Flutter分别是怎么渲染的?
43 | 剖析使 App 具有动态化和热更新能力的方案
用户故事 (1讲)
用户故事 | 我是如何学习这个专栏的?
结束语 (1讲)
结束语 | 慢几步,深几度
iOS开发高手课
登录|注册

09 | 无侵入的埋点方案如何实现?

戴铭 2019-03-30
你好,我是戴铭。
在 iOS 开发中,埋点可以解决两大类问题:一是了解用户使用 App 的行为,二是降低分析线上问题的难度。目前,iOS 开发中常见的埋点方式,主要包括代码埋点、可视化埋点和无埋点这三种。
代码埋点主要就是通过手写代码的方式来埋点,能很精确的在需要埋点的代码处加上埋点的代码,可以很方便地记录当前环境的变量值,方便调试,并跟踪埋点内容,但存在开发工作量大,并且埋点代码到处都是,后期难以维护等问题。
可视化埋点,就是将埋点增加和修改的工作可视化了,提升了增加和维护埋点的体验。
无埋点,并不是不需要埋点,而更确切地说是“全埋点”,而且埋点代码不会出现在业务代码中,容易管理和维护。它的缺点在于,埋点成本高,后期的解析也比较复杂,再加上 view_path 的不确定性。所以,这种方案并不能解决所有的埋点需求,但对于大量通用的埋点需求来说,能够节省大量的开发和维护成本。
在这其中,可视化埋点和无埋点,都属于是无侵入的埋点方案,因为它们都不需要在工程代码中写入埋点代码。所以,采用这样的无侵入埋点方案,既可以做到埋点被统一维护,又可以实现和工程代码的解耦。
接下来,我们就通过今天这篇文章,一起来分析一下无侵入埋点方案的实现问题吧。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《iOS开发高手课》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(42)

  • 小前端
    感觉这篇文章适合做原理讲解,实用性不大。实际业务场景中会需要抓取页面id,控件id,控件内容,事件类型,埋点类型(比如曝光还是事件),很复杂的,而这些信息都需要在具体的业务中获取。至少本文这套理论是做不到的。运营和产品也不会按照什么view path来分析结果。

    作者回复: 客户端只能负责采集数据,采集的数据到了服务端,还需要进行功能标注。关于业务数据依赖在服务端做关联,不过标注的内容维护成本依然很大,对于客户端开发人员来说是减轻了工作量,而工作量转接到了维护标注的人那。

    2019-03-30
    1
    32
  • 鹏哥
    交换方法的代码有的说放在load方法,有的说放在load方法里面影响了启动速度,应该移到initalize方法中,所以,老师,你怎么看的?
    2019-04-01
    1
    14
  • 张蒙
    利用Aspects,实现面向横切编程,在加上资源增量更新可以实现动态无痕埋点。
    2019-03-30
    12
  • Geek_d4991f
    建议可以读下mixpanel,基本市面上的全埋点、无埋点都是基于此方案的优化,不过mixpanel的hook存在递归无法退出问题,需要优化
    2019-04-03
    6
  • Damon
    hook最好放在load中而不是InInitialize中,是跟调用的机制有关系,同时类别中实现了InInitialize会覆盖本类的InInitialize方法,有些场景不适用(比如本类和类别都做了方法hook),而load则能满足这种场景,所以最好在load中做hook,也可以根据业务场景选择是在load还是在InInitialize中hook
    2019-05-14
    4
  • drunkenMouse
    1.为什么不把+load方法移到initalize?既然是单例的话,不用担心子类调用父类的重复调用吧?
    2.为什么不建一个基于UIViewController的基类,然后重写ViewWillAppear与ViewDidAppear?只要保证所有的UIViewController都继承这个基类就可以的吧。

    作者回复: 实际工程可以这么做,没有问题的

    2019-03-31
    4
  • ssala
    埋点如果要携带业务数据的话,本身就是一件很复杂很特化的问题了,除了手动埋点以外没有更好的方式,硬是把无埋点这套逻辑往上套的话,除了徒增复杂度以外,没什么好处。
    2019-04-02
    3
  • Geek_de8948
    一直觉得采用切面编程实现埋点都是理论上,实际是不可行的。
    因为如果项目集成bugly这种第三方sdk时,他们也是切面,你埋掉也切,这种相互各种交换方法系统方面,肯定会导致一个失效。
    这个问题困扰了很久,不知道老师咋看。
    比如我现在项目由于早期就使用了bugly,导致我现在就不敢随意切。

    作者回复: 是的,从发展来看,通过 Clang 打桩可能更适合

    2019-04-01
    1
    3
  • Geek_53637b
    实际埋点需求中,埋点往往和业务数据强相关,比如点击页面上的加车按钮,埋点上报的数据中需要有商品id,当前商品的促销类型,商家id等等,这类需求暂时没有很好的无痕埋点方案
    2019-03-31
    2
  • 筇琼
    戴老师,你好,当我有两个类扩展,都通过运行时交换了ViewWillAppear方法,此时会崩溃,请问这个改如何避免,这个崩溃是必然的吗?还是由于我加入扩展的顺序导致的?

    作者回复: 需要避免 hook 冲突

    2019-03-30
    2
  • Kim
    我的实现方案

    ```
    @implementation UITableView (SMHook)
    + (void)load {
        SEL fromSelector = @selector(setDelegate:);
        SEL toSelector = @selector(sm_toDelegate:);
        
        [SMHook hookClass:self fromSelector:fromSelector toSelector:toSelector];
    }

    - (void)sm_toDelegate:(id <UITableViewDelegate>)delegate {
        [self sm_toDelegate:delegate];
        // 得到代理对象,代理对象会调用代理方法
        SEL fromSelector = @selector(tableView:didSelectRowAtIndexPath:);
        SEL toSelector = @selector(sm_tableView:didSelectRowAtIndexPath:);
        
        // 得到被替换的类的实例方式
        Method fromMethod = class_getInstanceMethod(delegate.class, fromSelector);
        // 得到替换的类的实例方法
        Method toMethod = class_getInstanceMethod(self.class, toSelector);
        
        // class_addMethod 添加要替换的方法
        class_addMethod(delegate.class, toSelector, method_getImplementation(toMethod), method_getTypeEncoding(toMethod));
        Method hookMethod = class_getInstanceMethod(delegate.class, toSelector);
        method_exchangeImplementations(fromMethod, hookMethod);
        
    }

    -(void)sm_tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        NSLog(@"aaa");
        [self sm_tableView:tableView didSelectRowAtIndexPath:indexPath];
    }


    @end
    ```
    2019-06-06
    1
  • Geek_麟凤来思
    老师,能每篇做个demo吗?只说没具体实现,还是不会啊!
    2019-05-14
    1
    1
  • 🐰先生
    给button 或者其他View 埋点的时候,可不可以通过给这个Button设置 Tag值,来达到唯一标识的目的

    作者回复: 关键是 tag 映射说明表的维护成本还是有的

    2019-04-10
    1
  • 怪兽
    有两个问题请教:
    1.事件唯一标识:子视图在父视图中的索引怎么获取
    2.统计到数据后怎么根据这个事件唯一标识分析数据,大数据分析师怎么知道这个唯一标识是哪个业务按钮或业务事件

    作者回复: 1.subviews 遍历索引
    2.在后台标注,可以配合测试过程中上传截图做匹配。

    2019-04-03
    1
  • 家有萌柴fries
    “我倒是觉得使用 Clang AST 的接口,在构建时遍历在构建时遍历 AST,通过定义的规则将所需要的埋点代码直接加”,这个会在之后的文章再具体介绍介绍么?

    作者回复: 会的

    2019-04-02
    1
  • 追想画廊
    课后作业 hook tableView: didSelectRowAtIndexPath:就好了 不过得hook NSObject这种基类
    需要注意的是为了避免其他类出现的同名的方法 还得判断一下 tableView是不是UITableView的子类
    2019-03-31
    1
  • 木昜
    老师,问一下,针对tap手势进行作业时,先hook掉initwithtarget方法,然后再交换传递进来的action方法,那么针对vc里面添加了多个Ges对应的action操作,怎么保证action和我们写的swizzle_action是一一对应的…就是ac1对应swizzle_ac1,ac2对应swizzle_ac2,能动态实现吗?根据外界传入不同的action,生成不同的swizzle_ac……求指点
    2019-11-15
  • Baan
    学到了
    2019-09-05
  • Swift_yong
    看了好多, Clang 编译层面的东西不会写, 我太难了, 感觉找不到学习这部分的入口一样
    2019-08-21
  • 白浩泉
    戴老师您好,我理解Clang AST类似的插装技术只是解决了hook的问题,在添加埋点代码的时候一样要解决view唯一标识的问题,目前最大的问题就是没法找到一个稳定的view标识 望解答,谢谢!

    作者回复: Clang AST 不是运行时的,静态可以通过代码级逻辑精准控制

    2019-06-20
收起评论
42
返回
顶部