自定义可复用统计SDK设计

本文介绍了在iOS开发中,如何设计一个可复用、低耦合的统计SDK,以解决传统统计方式的复用性和维护性问题。通过使用Runtime的Method Swizzling技术,实现了页面展示、离开次数以及收藏、分享等事件的统计,同时通过配置表减少代码维护成本。文章还讨论了如何通过单元测试确保SDK在代码重构时的稳定性。
摘要由CSDN通过智能技术生成

之前换工作,有家公司福利待遇各方面都特别满意,十分想去,但是面试碰到个问题,让我尴尬了,虽然本人到目前为止从事iOS开发三年多,但大多独立开发,这问题还真没深入去考虑过。下面我具体讲讲遇到的问题。

首先,那个公司的项目要自己开发统计的sdk,不用第三方库,主要是考虑到数据安全的问题,这其实没什么,自己开发就自己开发吧,然后,面试官问我开发这个sdk的思路是什么,应该怎么去做,然后我滔滔不绝的把友盟统计的实现原理与步骤吧啦吧啦讲讲一遍,但是,他紧接着就问我一个问题,说:你不觉得这样做,耦合度很高吗?统计的代码分散在工程的各个角落,维护或修改起来多麻烦?当时我就震惊了……what?……你如果要统计按钮点击次数,你不在按钮实现方法里加个统计的代码,那要怎么做呢?因为从来没考虑过这方面的问题,所以当时我的脑子是空白的。

理所当然的面试失败,回到家,我痛定思痛,深入研究了一下,在这里写一下我的心得,有不对的地方希望留言指正。

首先传统统计,例如友盟,他有以下几个缺点:

1.复用性差,这部分埋点代码很难给其他项目复用,复用性基本为零

2.工作量大,尤其在页面较多时,需要修改的代码也多

3.引入“脏代码”,不易维护,尤其是稍微大一点的app,这样的代码几乎遍地都是 (这里的脏代码指的是用户行为分析这种业务其实跟主业务没有关系,不应该保持如此高的耦合度,因为这些代码会干扰我们对项目主业务的维护)

因此,采用这种传统的代码,虽然直观,方便,但是在可复用性以及可维护性来说,有很大的缺陷。我在网上看了很多的博客论坛之类的,总结一下可以用runtime来有效的解决这一问题。

由于Runtime知识不属于本文的重点,这里只简单介绍。

在iOS中,我们可以在运行时替换两个方法的实现,达到“勾住”某个方法并注入代码的目的。具体做法是:

重载类的“+(void)load”方法,在程序加载到内存时利用Runtime的method_exchangeImplementations等接口将方法(设为M)的实现互相交换。当方法M被调用时就会被勾住(Hook),执行我们的方法。

这种技术也称为Method Swizzling,属于面向切面编程(Aspect-Oriented Programming)的一种实现。

替换两个方法的实现,代码一般长酱紫:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@interface WHookUtility : NSObject
+ (void)swizzlingInClass:(Class)cls originalSelector:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector;
@end
@implementation WHookUtility
+ (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);
     }
}
@end

这个WHookUtility工具类下文会用到。比如现在我们要勾住UIViewController的viewWillAppear:方法,可以这样做:

1
2
3
4
5
6
7
8
  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值