当前位置: 首页 > 科技观察

问题记录:iOS用户行为统计代码剥离

时间:2023-03-20 23:40:42 科技观察

这两天一直在做一个统计模块,记录遇到的问题和一些讨论,所以这篇文章没有答案,没有解决方案,只是讨论。我应该怎么办?我现在做的是一个app里面的用户行为统计。简单的说,就是记录用户跳转到了哪个页面,在该页面点击了哪些按钮,点击了多少次等等。统计工具使用现成的GoogleAnalytics、Flurry和MixPanel。我要做的就是将它们集成到我的统计模块代码中,对各种业务事件进行统计。以Flurry为例,调用登录按钮clickShootButtonAction做一次用户行为统计,统计代码是这样的-?(IBAction)clickShootButtonAction{????//?在?Flurry?的背景下执行以下语句可以看到这个事件的记录????[Flurry?logEvent:@"Clickthecamerabutton"];}or-?(IBAction)clickShootButtonAction{????//?在?Flurry中执行下面这句话可以在??????//?的后台看到这个事件的记录不同的是这里记录的是一个用户的行为路径????//?表示:用户拍完照片后,在照片Page分享,将照片分享到?Facebook?????[Flurry?logEvent:@"Savethesharedphoto"?withParameters:{@"Shareto":@"Facebook"}];}并记录数百个用户在应用中的行为是很正常的事情。也就是说,像上面这样的代码在Controller中可能会出现上百次,并且散落在各处。这是正常的吗?如果这些代码遍布我们的项目,那么统计模块和业务代码的耦合度会极高,导致剥离困难,无法复用等各种问题,写起来会很累。对于我们来说,理想情况下,Controller中这样的代码越少越好。充其量根本就没有一行,如果能包含一个头文件来自动计数就好了。因为如果你想剥离统计代码或改变统计方法,这是非常方便的。但实际情况并不乐观!!!有解决办法吗?根据统计事件,我们大致将需要统计的方法分为以下三种,统计剥离的难度也在一步步增加。类似于viewDidLoad,viewWillAppear,ViewController生命周期的一个方法;一个方法,一旦调用就进行事件统计;方法中,满足条件才计数的方法;那么问题来了,如果我们不想直接在Controller中添加统计代码,那上面三个方法应该怎么统计呢?剥离ViewController生命周期的统计代码比较简单。写一个UIViewController的类,hookUIViewController中需要统计的方法,然后把头文件塞进要统计的ViewController中。剥离统计一次调用的代码。统计代码的剥离比较麻烦。麻烦的一点是,这些方法是根据业务逻辑生成的。各个ViewController中的方法不一致,无法统一处理。关于这种代码的剥离,我查了一些资料,咨询了一些同学,在一些技术群里讨论过。剥离确实可以,但是方法不是很靠谱,所以不推荐使用。下面一一列举。方法一:AOP+SPOC配置文件?这个方法来自于最近上传的《禅与 Objective-C 编程艺术》***sectionAspect-OrientedProgramming。通过在SPOC配置文件中添加类名和方法,将类中的方法hook起来,然后进行统计。乍一看,这个思路很好,写起来爽。当你想添加统计代码时,只需要在配置文件中添加就可以了。但是后来想想,这个方法在实际执行中会有问题。首先,统计模块代码和业务代码分散在两处,将具体类名和方法名的字符串hook后进行统计操作。因为统计模块比较独立,一个人写,其他人写业务代码。业务开发同学随意修改一个方法名是很正常的。业务开发的同学改了一个方法的名字,一般不会认为统计这边也会改;统计专业的学生不知道商科学生发生了什么变化。所以这种调试只在遇到统计异常时才检查,可维护性太差。所以这个方法写的人好,维护的人就非常非常不爽!?所以不推荐这个!方法2:同意方法名称?从开发之初就约定好,比如需要统计的函数(比如IBAction,按照约定命名),然后hookobjc-sendmessage函数统计需要的方法。这个方法其实和方法一差不多,所以也有同样的问题。此外,人为的协议并不特别具有约束力。如果一不小心就忘记了方法名上的约定,而且没有编译器警告或错误提示,此时你永远不会想到按约定的规则命名。此外,需求也在不断变化。一些之前不需要统计的内容突然需要重新统计。根据这个规则,方法名必须改变。总体感觉场面太混乱了。所以不推荐这个!没有办法剥离符合条件的统计代码来统计!想想过去真是莫名其妙!因为我们前面使用的方法和思路基本上都离不开AOP,而AOP本身就是一个hook方法,在方法前后添加一些自定义的操作。AOP没有办法了解方法内部是什么,更不用说统计方法中满足某些条件的事件了。该怎么办?老实说,把统计代码写到相关的方法里,真的没办法!***的悲哀折腾了那么久,结果还是无法把统计代码和业务代码分开。本以为统计模块应该是一个独立的模块,结果却被插入到各个Controller代码中,真是悲哀。那么这样的结局到底是什么原因呢?回过头来看,我们从一开始就默认统计模块是一个独立的模块,应该和业务逻辑分开。但其实统计是一个和业务紧密结合的模块,是不是可以这样想。统计模块的代码是否也属于业务逻辑?反正这样一想,就可以安心的把统计代码写进Controller了~