iOS 实现页面统计功能的DEMO

       前段时间公司开始禁止使用第三方sdk,这对于程序猿的我来说无疑是一次毁灭性的打击,开发时间变得无可估量了,其中分配到我名下的任务就是要仿造友盟数据统计收集这个功能,这个东西说难不难,说简单不简单,数据统计肯定要求数据的准确性,首先要完成的是统计页面使用这个模块。今天这里就说说统计页面使用这个模块的思路,同时附上代码,由于开发时间紧迫,代码的封装性简洁性不那么强,重在理解思路,没有思路就不可能实现业务逻辑。

        首先要搞明白一点,数据收集的目的说白了就是更加深入了解用户习惯和用户行为,通过分析这些数据能更好的理解用户意图,从而改进提高产品的质量。大数据的时代,没有统计数据这块的产品肯定会落伍。

         下面直接正题不废话,进入页面使用统计这个模块正题。

         需求:用户每进入一个页面就需要对该次操作进行记录,包括页面(ViewController)的title, 上一个页面(LastViewController)的title,进入该页面的时间等等字段需要记录。

        思路:首先要进行准确的统计,必须要先了解控制器(ViewController)的生命周期,生命周期有按照以下顺序进行调用:

当一个视图控制器被创建,并在屏幕上显示的时候。 代码的执行顺序

1、 alloc                                   创建对象,分配空间

2、init (initWithNibName) 初始化对象,初始化数据

3、loadView                          从nib载入视图 ,通常这一步不需要去干涉。除非你没有使用xib文件创建视图

4、viewDidLoad                   载入完成,可以进行自定义数据以及动态创建其他控件

5、viewWillAppear              视图将出现在屏幕之前,马上这个视图就会被展现在屏幕上了

6、viewDidAppear               视图已在屏幕上渲染完成

当一个视图被移除屏幕并且销毁的时候的执行顺序,这个顺序差不多和上面的相反

1、viewWillDisappear            视图将被从屏幕上移除之前执行

2、viewDidDisappear             视图已经被从屏幕上移除,用户看不到这个视图了

3、dealloc                                 视图被销毁,此处需要对你在init和viewDidLoad中创建的对象进行释放

那么问题就来了,我们需要对页面进行准确的统计,那么我们记录控制器被使用的方法必须写在唯一的系统API里面,那么首先就可以把viewWillAppear、viewWillDisappear 排除在外,明显这两个方法不符合我们的需求,因为控制器无论调用viewDidLoad 还是从上级页面调popViewControllerAnimated 这个方法,当前页面都会调用viewWillAppear这个函数,这就会导致我们统计页面的数据不准确。那么再回到上面几个方法里看,alloc init更不可能,这些方法只是让控制器在系统中分配内存并初始化,并不适合写入我们记录控制器的操作,至于loadview这个方法也不太现实,特别是纯代码构建视图的童鞋,更加要排除在外,那么只剩下viewDidLoad、viewDidDisappear、dealloc这三个方法适合我们去写入我们想要记录控制器被使用记录的代码了,这里我选择了viewDidLoad、dealloc这两个方法里做文章,原因很简单,这两个函数在整个控制器的生命周期百分百的只会被调用一次,不可能再多,那就满足了我们的需求了。好了,首先我们明确了我们该在哪个系统方法里去做文章了,接下来就是解决怎么做文章的问题了。

       每个控制器都要统计被使用的次数,那么这里我们要尽可能的去把通用的东西提炼出来,确保效率。我们首先统计每个控制器被初始化时候的数据(生成这个页面的数据记录),这里我创建了一个管理类,当然是个单例,代码如下


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(@“lastPage—%@“,str);

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

}

@end



然后我们只需要在每个控制器的viewDidLoad方法里面调一句代码就可以记录当前控制器和上级控制器了,代码如下:

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

注意:这句代码要在你设置完控制器的title后调用!!!!

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

关于控制器的销毁怎么去记录:一般我们在项目里头, 所有的控制器都会继承自一个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);

}

因为每次控制器在调用popViewControllerAnimated之后就会调用dealloc,也可以理解为当返回上一级页面时我就把上一级页面的currentpage和lastpage两个字段给记录下来。

到这里 我们就能完整的保证了每个页面在用户的使用中显示一次记录一次,保证了准确性,时间有限,肯定有不少疏漏之处,这仅仅是给和我一样遭遇的童鞋一个思路,如有错误请指正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容

  • *7月8日上午 N:Block :跟一个函数块差不多,会对里面所有的内容的引用计数+1,想要解决就用__block...
    炙冰阅读 2,441评论 1 14
  • 祖宗的牌位下是长不出莲花来的。——胡说八道的我语 众所周知,中国是一个具有五千年历史的文明古国(尽管国外史学界也有...
    巴图鲁阅读 519评论 14 16
  • 今天、我站在阳台上、 沐浴在阳光里、 感受着风的流动、 寒...
    璇轶阅读 108评论 0 0
  • 听南音,像偶遇一位故人。话还不及说,过往幕幕一帧一帧闪过,如老电影,如抽屉深处泛黄的相册。 有些物件可以留住时间。...
    生活恋情阅读 399评论 0 0