上個版本產品說運營有這樣的需求,苦逼的程序員敲代碼了,然后趕緊打開友盟看到如下文檔:
文檔的意思是要在每個VC的viewWillAppear和viewWillDisAppear添加對應的代碼來實現統計功能,看著這里想想我們的app,這么多模塊和VC,如果每個界面都這樣寫勢必工作量會很大,那有沒有簡單可行的辦法呢?有啊,要不我寫這篇文章干嘛
實現思路 使用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表示當前方法調用的對象實例一樣。