iOS 實現(xiàn)頁面統(tǒng)計功能的DEMO

?????? 前段時間公司開始禁止使用第三方sdk,這對于程序猿的我來說無疑是一次毀滅性的打擊,開發(fā)時間變得無可估量了,其中分配到我名下的任務(wù)就是要仿造友盟數(shù)據(jù)統(tǒng)計收集這個功能,這個東西說難不難,說簡單不簡單,數(shù)據(jù)統(tǒng)計肯定要求數(shù)據(jù)的準確性,首先要完成的是統(tǒng)計頁面使用這個模塊。今天這里就說說統(tǒng)計頁面使用這個模塊的思路,同時附上代碼,由于開發(fā)時間緊迫,代碼的封裝性簡潔性不那么強,重在理解思路,沒有思路就不可能實現(xiàn)業(yè)務(wù)邏輯。

? ? ??? 首先要搞明白一點,數(shù)據(jù)收集的目的說白了就是更加深入了解用戶習(xí)慣和用戶行為,通過分析這些數(shù)據(jù)能更好的理解用戶意圖,從而改進提高產(chǎn)品的質(zhì)量。大數(shù)據(jù)的時代,沒有統(tǒng)計數(shù)據(jù)這塊的產(chǎn)品肯定會落伍。

???????? 下面直接正題不廢話,進入頁面使用統(tǒng)計這個模塊正題。

???????? 需求:用戶每進入一個頁面就需要對該次操作進行記錄,包括頁面(ViewController)的title, 上一個頁面(LastViewController)的title,進入該頁面的時間等等字段需要記錄。

? ? ? ? 思路:首先要進行準確的統(tǒng)計,必須要先了解控制器(ViewController)的生命周期,生命周期有按照以下順序進行調(diào)用:

當一個視圖控制器被創(chuàng)建,并在屏幕上顯示的時候。 代碼的執(zhí)行順序

1、 alloc ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 創(chuàng)建對象,分配空間

2、init (initWithNibName) 初始化對象,初始化數(shù)據(jù)

3、loadView ? ? ? ? ? ? ? ? ? ? ? ? ?從nib載入視圖 ,通常這一步不需要去干涉。除非你沒有使用xib文件創(chuàng)建視圖

4、viewDidLoad ? ? ? ? ? ? ? ? ? 載入完成,可以進行自定義數(shù)據(jù)以及動態(tài)創(chuàng)建其他控件

5、viewWillAppear ? ? ? ? ? ? ?視圖將出現(xiàn)在屏幕之前,馬上這個視圖就會被展現(xiàn)在屏幕上了

6、viewDidAppear ? ? ? ? ? ? ? 視圖已在屏幕上渲染完成

當一個視圖被移除屏幕并且銷毀的時候的執(zhí)行順序,這個順序差不多和上面的相反

1、viewWillDisappear ? ? ? ? ? ?視圖將被從屏幕上移除之前執(zhí)行

2、viewDidDisappear ? ? ? ? ? ? 視圖已經(jīng)被從屏幕上移除,用戶看不到這個視圖了

3、dealloc ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 視圖被銷毀,此處需要對你在init和viewDidLoad中創(chuàng)建的對象進行釋放

那么問題就來了,我們需要對頁面進行準確的統(tǒng)計,那么我們記錄控制器被使用的方法必須寫在唯一的系統(tǒng)API里面,那么首先就可以把viewWillAppear、viewWillDisappear 排除在外,明顯這兩個方法不符合我們的需求,因為控制器無論調(diào)用viewDidLoad 還是從上級頁面調(diào)popViewControllerAnimated 這個方法,當前頁面都會調(diào)用viewWillAppear這個函數(shù),這就會導(dǎo)致我們統(tǒng)計頁面的數(shù)據(jù)不準確。那么再回到上面幾個方法里看,alloc init更不可能,這些方法只是讓控制器在系統(tǒng)中分配內(nèi)存并初始化,并不適合寫入我們記錄控制器的操作,至于loadview這個方法也不太現(xiàn)實,特別是純代碼構(gòu)建視圖的童鞋,更加要排除在外,那么只剩下viewDidLoad、viewDidDisappear、dealloc這三個方法適合我們?nèi)懭胛覀兿胍涗浛刂破鞅皇褂糜涗浀拇a了,這里我選擇了viewDidLoad、dealloc這兩個方法里做文章,原因很簡單,這兩個函數(shù)在整個控制器的生命周期百分百的只會被調(diào)用一次,不可能再多,那就滿足了我們的需求了。好了,首先我們明確了我們該在哪個系統(tǒng)方法里去做文章了,接下來就是解決怎么做文章的問題了。

?????? 每個控制器都要統(tǒng)計被使用的次數(shù),那么這里我們要盡可能的去把通用的東西提煉出來,確保效率。我們首先統(tǒng)計每個控制器被初始化時候的數(shù)據(jù)(生成這個頁面的數(shù)據(jù)記錄),這里我創(chuàng)建了一個管理類,當然是個單例,代碼如下


PageCollectionManger.h

@interface PageCollectionManger : NSObject

- (void)viewControllerDidLoadByController:(BaseViewController *)currentController andPageName:(NSString*)pageName;

+(instancetype)sharedInstance;

@end

PageCollectionManger.m

@implementation PageCollectionManger {

}

static PageCollectionManger *manger = nil;

+(instancetype)sharedInstance {

return [[self alloc] init];

}

- (instancetype)init {

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

manger = [super init];

});

return manger;

}

+(instancetype)allocWithZone:(struct _NSZone *)zone{

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

manger = [super allocWithZone:zone];

});

return manger;

}

- (void)viewControllerDidLoadByController:(BaseViewController *)currentController andPageName:(NSString*)pageName{

NSMutableArray *array = [NSMutableArray arrayWithCapacity:0];

for (UIViewController *controller in currentController.navigationController.viewControllers) {

[array addObject:controller];

}

NSString *str = @"";

UIViewController *vc = [[UIViewController alloc] init];

if (array.count>=2) {

vc = array[array.count-2];

str = vc.title;

}

NSLog(@“l(fā)astPage—%@“,str);

NSLog(@“currentPage—%@“,currentController.title);

}

@end



然后我們只需要在每個控制器的viewDidLoad方法里面調(diào)一句代碼就可以記錄當前控制器和上級控制器了,代碼如下:

[[PageCollectionManger sharedInstance] viewControllerDidLoadByController:self andPageName:self.tilte];

注意:這句代碼要在你設(shè)置完控制器的title后調(diào)用?。。?!

到這里我們的工作只完成了一半,我們不能只管生,不管死。

關(guān)于控制器的銷毀怎么去記錄:一般我們在項目里頭, 所有的控制器都會繼承自一個BaseViewController這玩意,那么當然我們要在這個父類里去做手腳了,下面我把我寫的BaseViewController的代碼粘貼出來,這里只需要在delloc方法里去做文章,因為每一個控制器的銷毀意味著返回到上一級的控制器了,所以對于上一級控制器來說,當前控制器就是LastViewController,而上一級控制器只需要遍歷當前所有的控制器取索引為array.count-2即可。


BaseViewController.m

- (void)dealloc{

//pop的邏輯

[self gogogo];

NSLog(@"返回上一個頁面");

}

- (void)gogogo {

NSMutableArray *array = [NSMutableArray arrayWithCapacity:0];

for (UIViewController *controller in self.navigationController.viewControllers) {

[array addObject:controller];

}

NSString *str = @"";

UIViewController *vc = [[UIViewController alloc] init];

if (array.count>=2) {

vc = array[array.count-2];

str = vc.title;

}

NSLog(@"lastPage---%@",self.title);

NSLog(@"currentPage----%@",str);

}

因為每次控制器在調(diào)用popViewControllerAnimated之后就會調(diào)用dealloc,也可以理解為當返回上一級頁面時我就把上一級頁面的currentpage和lastpage兩個字段給記錄下來。

到這里 我們就能完整的保證了每個頁面在用戶的使用中顯示一次記錄一次,保證了準確性,時間有限,肯定有不少疏漏之處,這僅僅是給和我一樣遭遇的童鞋一個思路,如有錯誤請指正。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • *7月8日上午 N:Block :跟一個函數(shù)塊差不多,會對里面所有的內(nèi)容的引用計數(shù)+1,想要解決就用__block...
    炙冰閱讀 2,752評論 1 14
  • 祖宗的牌位下是長不出蓮花來的?!f八道的我語 眾所周知,中國是一個具有五千年歷史的文明古國(盡管國外史學(xué)界也有...
    巴圖魯閱讀 608評論 14 16
  • 今天、我站在陽臺上、 沐浴在陽光里、 感受著風(fēng)的流動、 寒...
    璇軼閱讀 176評論 0 0
  • 聽南音,像偶遇一位故人。話還不及說,過往幕幕一幀一幀閃過,如老電影,如抽屜深處泛黃的相冊。 有些物件可以留住時間。...
    生活戀情閱讀 537評論 0 0

友情鏈接更多精彩內(nèi)容