利用runtime实现友盟app页面访问路径功能

上个版本产品说运营有这样的需求,苦逼的程序员敲代码了,然后赶紧打开友盟看到如下文档:

屏幕快照 2017-02-09 下午2.27.46.png

文档的意思是要在每个VC的viewWillAppear和viewWillDisAppear添加对应的代码来实现统计功能,看着这里想想我们的app,这么多模块和VC,如果每个界面都这样写势必工作量会很大,那有没有简单可行的办法呢?有啊,要不我写这篇文章干嘛

6767C6CA1343747E7A943E26F088E99E.gif

实现思路 使用runtime:
1:拦截系统的viewWillAppear和viewWillDisAppear
2:交换为我们自己定义的方法
3:执行对应的统计方法beginLogPageView和endLogPageView
4: 继续执行原来方法

不想看文章的直接可以下载代码demo,觉得不错的请给我star谢谢😀

  • 创建UIViewController的分类UIViewController+AS.h

  • 在.m里实现load类方法 分享一个方便好用的runtime库

    + (void)load
    {
    
          Method viewWillAppear = class_getInstanceMethod(self, @selector(viewWillAppear:));
          Method new_viewWillAppear = class_getInstanceMethod(self, @selector(new_viewWillAppear:));
          method_exchangeImplementations(viewWillAppear, new_viewWillAppear);
          
          Method viewWillDisappear = class_getInstanceMethod(self, @selector(viewWillDisappear:));
          Method new_viewWillDisappear = class_getInstanceMethod(self, @selector(new_viewWillDisappear:));
          method_exchangeImplementations(viewWillDisappear, new_viewWillDisappear);
    }
    
  • 实现替换的方法 (self.title就是每个导航栏上的title,对于没有使用导航栏或者是导航栏title并不能区分是哪个模块的那个页面,(都是商品详情页,但是一个是品牌馆模块,一个是超市模块)这种情况需要给系统的UIViewController添加自定义属性)标记问题1文章末尾会解决
    - (void)new_viewWillAppear:(BOOL)animated{
    if (self.title.length) {

              [MobClick beginLogPageView:self.title];
              NSLog(@"路径开始%@==%@  %s",NSStringFromClass(self.class),self.title,__func__);
          }
          [self new_viewWillAppear:animated];
      }
    
      - (void)new_viewWillDisappear:(BOOL)animated{
          if (self.title.length) {
              NSLog(@"路径结束%@==%@ == %s",NSStringFromClass(self.class),self.title,__func__);
              [MobClick endLogPageView:self.title];
          }
          [self new_viewWillDisappear:animated];
      }
    
  • 我们的代码规范是在每个VC的loadView方法里去写一些当前vc显示的相关的代码.比如在AViewController里,可以这样:
    - (void)loadView{
    [super loadView];
    self.title = @"我是AVC界面";
    }

以上就可以少量代码实现行为路径的统计,具体可以看代码,毕竟代码才是程序员沟通的语言😀

使用runtime给系统类添加属性
接上边的问题1,给ViewController添加自定义属性:

  • 在分类UIViewController+AS.h 中声明一个属性为@property (copy, nonatomic) NSString *umengLogAs;

  • 实现set get方法
    - (void)setUmengLogAs:(NSString *)umengLogAs{

          objc_setAssociatedObject(self, @selector(umengLogAs), umengLogAs, OBJC_ASSOCIATION_COPY_NONATOMIC);
      }
    
      - (NSString *)umengLogAs
      {
          // 根据关联的key,获取关联的值。
          return objc_getAssociatedObject(self,  _cmd) ;
      }
    

打完,收工!

_cmd 是什么: 在Apple的官方介绍里看到轻描淡写的说了一句:“The _cmd variable is a hidden argument passed to every method that is the current selector”,其实说的就是_cmd在Objective-C的方法中表示当前方法的selector,正如同self表示当前方法调用的对象实例一样。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,824评论 0 9
  • 转载:http://yulingtianxia.com/blog/2014/11/05/objective-c-r...
    F麦子阅读 774评论 0 2
  • 本文转载自:http://yulingtianxia.com/blog/2014/11/05/objective-...
    ant_flex阅读 805评论 0 1
  • 我们常常会听说 Objective-C 是一门动态语言,那么这个「动态」表现在哪呢?我想最主要的表现就是 Obje...
    Ethan_Struggle阅读 2,236评论 0 7
  • 本文详细整理了 Cocoa 的 Runtime 系统的知识,它使得 Objective-C 如虎添翼,具备了灵活的...
    lylaut阅读 831评论 0 4