ios无码统计埋点总结 一

第一种方式就是业务代码与统计代码相分离,利用runTime的特性,具体操作如下

定义工具类

@interface WHookUtility : NSObject

+ (void)swizzlingInClass:(Class)cls originalSelector:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector;

@end

#import <objc/runtime.h>

+ (void)swizzlingInClass:(Class)cls originalSelector:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector

{

Class class = cls;

Method originalMethod = class_getInstanceMethod(class, originalSelector);

Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

BOOL didAddMethod =

class_addMethod(class,

originalSelector,

method_getImplementation(swizzledMethod),

method_getTypeEncoding(swizzledMethod));

if (didAddMethod) {

class_replaceMethod(class,

swizzledSelector,

method_getImplementation(originalMethod),

method_getTypeEncoding(originalMethod));

} else {

method_exchangeImplementations(originalMethod, swizzledMethod);

}

}

对于以上的函数需要有以下说明:

1 上面的函数主要作用就是交换两个方法的实现,主要的三句代码是:

Method originalMethod = class_getInstanceMethod(class, originalSelector);

Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

method_exchangeImplementations(originalMethod, swizzledMethod);

让我举个栗子��:比如你需要统计一个viewController的生命周期开始和结束,那一搬情况下是不是需要在它的

viewWillAppear viewDidDisappear里面写上一句监听的代码[UMXXXX trackEvent:@"EventName"]

如果在每个页面里面都这样写,那么统计这一块的代码耦合很高,这样很不好。现在有一个解决方法,利用RunTime特性Hook住

viewWillAppear viewDidDisappear 这两个函数。具体实现原理看以下UIViewController+userStatics.h

的demo。

2 除了函数的主要作用的三句代码那class_addMethod class_replaceMethod 的作用是什么呢

假如你hook的函数并不存在比如随意一个函数viewWillShow 那么这两句代码就稍微有点有作用了,至少你在你hook的

那个类里面执行[self performSelector:@selector(viewWillShow) withObject:nil]不会崩溃。

(前提是你已经定义好了交换的函数哦)。总的来说只要你不莫名其妙的写出hook不存在的函数,这两个函数是没用的。

即使hook了不存在的函数也不会崩溃的。如果你发现这两句代码还有其它的作用,可以交流一下~

现在我们来使用一下以上的类

建一个基于UIViewController的类别

#import "UIViewController+userStatics.h"

#import "WHookUtility.h"

@implementation UIViewController (userStatics)

+ (void)load {

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

SEL originalSelector = @selector(viewWillAppear:);

SEL swizzledSelector = @selector(swiz_viewWillAppear:);

[WHookUtility swizzlingInClass:[self class] originalSelector:originalSelector swizzledSelector:swizzledSelector];

SEL originalSelectorDis = @selector(viewWillDisappear:);

SEL swizzledSelectorDis = @selector(swiz_viewWillDisappear:);

[WHookUtility swizzlingInClass:[self class] originalSelector:originalSelectorDis swizzledSelector:swizzledSelectorDis];

});

}

#pragma mark - Method Swizzling

swiz_viewWillAppear:(BOOL)animated  swiz_viewWillDisappear:(BOOL)animated 是我自己在类别里面定义的函数,

在以上的load函数里面我将它们与 viewWillAppear: viewWillDisappear: 交换了。所以当一个类里面执行viewWillAppear:

它事实上执行的是函数swiz_viewWillAppear:(BOOL)animated 你会发现在函数swiz_viewWillAppear:(BOOL)animated

里面有句代码 [self swiz_viewWillAppear:animated]; 由于交换的原因它事实上执行的是函数viewWillAppear:。

- (void)swiz_viewWillAppear:(BOOL)animated

{

//插入需要执行的代码

NSLog(@"我在viewWillAppear执行前偷偷插入了一段代码%@",[self class]);

//不能干扰原来的代码流程,插入代码结束后要让本来该执行的代码继续执行

[self swiz_viewWillAppear:animated];

}

- (void)swiz_viewWillDisappear:(BOOL)animated

{

//插入需要执行的代码

NSString *pageName=NSStringFromClass([self class]);

NSLog(@"结束监听%@",pageName);

//不能干扰原来的代码流程,插入代码结束后要让本来该执行的代码继续执行

[self swiz_viewWillDisappear:animated];

}

这种runTime方法也可以用在其它的类比如监听整个app的按钮点击:

#import "UIControl+userStatics.h"

#import "WHookUtility.h"

@implementation UIControl (userStatics)

+ (void)load {

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

SEL originalSelector = @selector(sendAction:to:forEvent:);

SEL swizzledSelector = @selector(swiz_sendAction:to:forEvent:);

[WHookUtility swizzlingInClass:[self class] originalSelector:originalSelector swizzledSelector:swizzledSelector];

});

}

#pragma mark - Method Swizzling

- (void)swiz_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event;

{

//插入埋点代码

[self performUserStastisticsAction:action to:target forEvent:event];

[self swiz_sendAction:action to:target forEvent:event];

}

- (void)performUserStastisticsAction:(SEL)action to:(id)target forEvent:(UIEvent *)event;

{

NSLog(@"\n***hook success.\n[1]action:%@\n[2]target:%@ \n[3]event:%ld", NSStringFromSelector(action), target, (long)event);

}

但是这种方法有一个突出的问题解决不了:无法交换代理函数

你如果想要监听webview的代理函数,tableView的代理函数那就无法用这种方法了。

ios 无码统计埋点相关推荐

  1. Cobub无码埋点关键技术的实现

    随着大数据时代的到来,数据采集也已经变的越来越重要.前端埋点作为一个比较成熟的数据接入手段被广泛应用着.目前埋点分为两种方式,有码与无码埋点.有码埋点比较容易理解,即调用SDK的API,在代码中插入埋 ...

  2. 【无码专区7】括号序列(思维)

    因为只有std,没有自我实现,所以是无码专区 主要是为了训练思维能力 solution才是dls正解,但是因为只有潦草几句,所以大部分会有我自己基于正解上面的算法实现过程,可能选择的算法跟std中dl ...

  3. 【无码专区2】序列划分(数学)

    有std,但是没有自我实现,所以是无码专区 description 完全由数字组成的字符串 sss,划分成若干段,每一段看成一个十进制的数(允许前导零)求有多少种划分方法使得相邻两个数至少一个是 DD ...

  4. php淘金农场源码,2018Thinkphp仿淘金农场开源源码统H5农场复利源码带商城仓库商店...

    演示地址:如有演示站请以演示为准,无演示站以截图为准,源码太多服务器有限,无法搭建所有源码演示站,请谅解! 新手购买指导:1.在本站注册账号 丨 2.登录已注册账号充值源码所需金币 丨 3.登录账号下 ...

  5. 华为 A199 / Ascend G710摄像头拍摄样张 多图 高清无码 慎入

    前方高能反应,华为 A199 / Ascend G710摄像头拍摄样张,多图.高清.无码!   废话少说,直接来个连拍的,发现华为A199的连拍速度还不错,不过连拍的张数比较少 今天的天气灰蒙蒙的,但 ...

  6. 心中无码,自然高清 | 联合去马赛克与超分辨率研究论文Pytorch复现

    作者 | 知凡,个人公众号:林木蔚然读书会(ID:EspressoOcean),知乎ID:Uno Whoiam 本文授权转载自知乎 本文结构 简单扫盲 什么是去马赛克 什么是超分辨率 <Deep ...

  7. 开源ImageFilter库For IOS源码发布

    开源ImageFilter库For IOS源码发布        鉴于之前有朋友反映将ImageFilterForC直接用于XCODE开发会报出错误的原因.最近正好入手一部MAC PRO,所以顺便将I ...

  8. 【无码专区13】最小公倍数(线段树)

    因为只有std,没有自我实现,所以是无码专区 主要是为了训练思维能力 my idea顾名思义,记录了我的整个思维过程,以及自己部分实现细节口胡,还有期望分数 solution才是dls正解,但是因为只 ...

  9. 【无码专区12】子集和(背包dp)

    此题已自我实现,但仍归于无码专区 本题在考场上就过了,所以难度并不高,发现性质即可. problem 有 nnn 个正整数 a1,a2,...,ana_1,a_2,...,a_na1​,a2​,... ...

最新文章

  1. Intel SGX Remote Attestation实例代码安装和执行,笔记
  2. ActiveMQ入门系列二:入门代码实例(点对点模式)
  3. 1.6 Java字节流的使用:字节输入/输出流、文件输入/输出流、字节数组输入/输出流
  4. 前端学习(2853):简单秒杀系统学习之页面事件
  5. 机器视觉:锡膏印刷质量3D检测光学系统
  6. JavaScript、canvas小球加速和减速运动
  7. python多叉树_python中高效的四叉树实现
  8. 2007 word打开无响应
  9. 阿里云云开发平台的创建与部署
  10. java 数据库密码加密解密方法
  11. 万里长城第一里——实习之后台开发
  12. 「小猪佩奇」:成功儿童IP背后的商业逻辑和方法论
  13. Failed to resolve org.junit.vintage:junit-vintage-engine:5.6.2
  14. Opencv+Python学习记录9:掩膜(掩码)的使用(内附详细代码)
  15. 简单易懂的小学除法思维导图
  16. 鲸落送书第二期清华出版社系列丛书
  17. 几款微博同步工具比较
  18. 2021年R2移动式压力容器充装复审考试及R2移动式压力容器充装证考试
  19. Fama-French 三因子模型在A股市场的实证研究
  20. 蓝牙4.0android开发,Android蓝牙4.0开发

热门文章

  1. js 类数组转成真正的数组的方法
  2. navicat通过ssh连接mysql
  3. 计算机桌面图标出现蓝框,win10系统如何取消桌面蓝框
  4. nginx的编译安装
  5. win7能装HTML5年吗,十年老电脑装xp还是win7比较好
  6. 螺旋矩阵【史上最详细解释】
  7. 用matplotlib画画,这个小海豚惊到我了
  8. 《Java》小项目,吃货联盟
  9. ios 真机上可以运行模拟器编译报错
  10. graphviz linux 运行,绘图工具Graphviz学习使用