美文网首页iOS面试
iOS - 无痕埋点+数据统计+记录用户行为轨迹

iOS - 无痕埋点+数据统计+记录用户行为轨迹

作者: 路飞_Luck | 来源:发表于2019-02-16 17:57 被阅读21次
序言

该功能的实现是基于 Aspects 框架实现的,之前已经有对该框架做了深入的讲解,感兴趣的朋友可以先行阅读。iOS-Aspects框架详解

实现

调用Aspects框架的aspect_hookSelector方法对方法进行 hook

[BaseViewController aspect_hookSelector:@selector(viewDidLoad) withOptions:AspectPositionBefore usingBlock:^(id<AspectInfo> aspectInfo) {
    BaseViewController *vc = aspectInfo.instance;
    if (!vc.dataModel) vc.dataModel = [DataCubeModel new];
    // 未设置别名使用控制器名
    if (vc.dataModel.alias_page == nil) {
        NSDictionary *dict = [DataCubeTracker sharedIntance].cubeMapp;
        [dict enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL *stop) {
            __block BOOL isContain = NO;
            if ([obj containsString:@","]) {
                NSArray *objArr = [obj componentsSeparatedByString:@","];
                [objArr enumerateObjectsUsingBlock:^(NSString *obj1, NSUInteger idx, BOOL *stop1) {
                    if ([obj1 isEqualToString:NSStringFromClass([vc class])]) {
                        isContain = YES;
                        *stop1 = YES;
                    }
                }];
            }else{
                if ([obj isEqualToString:NSStringFromClass([vc class])]) {
                    isContain = YES;
                }
            }
            if (isContain) {
                if ([key containsString:@"|"]) {
                    key = [[key componentsSeparatedByString:@"|"] firstObject];
                }
                vc.dataModel.alias_page = key;
                *stop = YES;
            }
        }];
    }
    if (vc.dataModel.alias_page == nil) {
        vc.dataModel.alias_page = NSStringFromClass([vc class]);
    }
} error:NULL];

简单解读一下上述方法

    1. 先定义一个 VC 的基类为BaseViewController,封装一个模型对象DataCubeModel,里面定义一些变量名,比如上一页 VC 名称,当前页 VC 名称等。基类定义该变量,如果当前控制器的别名为空,则根据之前定义好的给该控制器取一个名称。

事先定义一个字典,里面定义了当前工程所有控制器所对应的别名。

"NewPasswordPage|重置密码": "ChangePasswordViewController",
"CategoryIndexPage|分类页": "CategoryViewController",
二 对viewWillDisappear:viewDidDisappear:方法进行 hook,然后使用全局变量保存即将要离开页面的相关数据
  • UITabBarController类型 VC 处理
[BaseViewController aspect_hookSelector:@selector(viewWillDisappear:) withOptions:AspectPositionBefore usingBlock:^(id<AspectInfo> aspectInfo ,BOOL animated){
    BaseViewController *vc = aspectInfo.instance;
    UITabBarController *presentVC = (UITabBarController *)vc.presentingViewController;
    if(presentVC){//只有modal出来的才会走
        [CSLibs sharedInstance].tmpPageAlias = vc.dataModel.alias_page;
        [CSLibs sharedInstance].tmpVisitPage = vc.dataModel.visit_page;
    }
} error:NULL];

  • BaseViewControllerVC 处理
[BaseViewController aspect_hookSelector:@selector(viewDidDisappear:) withOptions:AspectPositionBefore usingBlock:^(id<AspectInfo> aspectInfo ,BOOL animated){
    BaseViewController *vc = aspectInfo.instance;

    //只走一次
    if (![CSLibs sharedInstance].tmpPageAlias) {
        [CSLibs sharedInstance].tmpPageAlias = vc.dataModel.alias_page;
    }
    if (![CSLibs sharedInstance].tmpVisitPage) {
        [CSLibs sharedInstance].tmpVisitPage = vc.dataModel.visit_page;
        if (![CSLibs sharedInstance].tmpVisitPage) {
            [CSLibs sharedInstance].tmpVisitPage = vc.dataModel.alias_page;
        }
    }
    
} error:NULL];
三 对viewDidAppear:方法进行 hook,然后对相关数据进行赋值操作
[BaseViewController aspect_hookSelector:@selector(viewDidAppear:) withOptions:AspectPositionBefore usingBlock:^(id<AspectInfo> aspectInfo ,BOOL animated){
    BaseViewController *vc = aspectInfo.instance;
    UITabBarController *presentVC = (UITabBarController *)vc.presentingViewController;
    NSString *aliasPrevPage = [[CSLibs sharedInstance].tmpPageAlias copy];
    NSString *prevPage = [[CSLibs sharedInstance].tmpVisitPage copy];
    if(presentVC){//只有modal出来的才会走
        UINavigationController *navi;
        if ([presentVC isKindOfClass:[UITabBarController class]]) {
            navi = [presentVC selectedViewController];
        } else if([presentVC isKindOfClass:[UINavigationController class]]){
            navi = (UINavigationController *)presentVC;
        }
        NSArray *viewcontrollers = navi.viewControllers;
        BaseViewController *lastVC = nil;
        if(viewcontrollers.count >= 1){
            lastVC = [viewcontrollers objectAtIndex:viewcontrollers.count - 1];
        }
        if(lastVC && [lastVC isKindOfClass:[BaseViewController class]]){
            aliasPrevPage = lastVC.dataModel.alias_page;
            prevPage = lastVC.dataModel.visit_page;
        }
    }
    vc.dataModel.alias_prev_page = aliasPrevPage;
    vc.dataModel.prev_page = prevPage;
    
    [CSLibs sharedInstance].tmpPageAlias = nil;
    [CSLibs sharedInstance].tmpVisitPage = nil;

} error:NULL];

这样就将用户浏览过的页面全部都记录了下来,然后根据需要进行传值或上报相关数据即可。

相关文章

  • iOS - 无痕埋点+数据统计+记录用户行为轨迹

    序言 该功能的实现是基于 Aspects 框架实现的,之前已经有对该框架做了深入的讲解,感兴趣的朋友可以先行阅读。...

  • iOS 最优无痕埋点方案

    iOS 最优无痕埋点方案 在移动互联网时代,对于每个公司、企业来说,用户的行为数据非常重要。重要到什么程度,用户在...

  • AOP无痕埋点技术

    使用AOP实现iOS应用内的埋点计数 - 简书 iOS用户行为追踪——无侵入埋点 - CSDN博客 iOS 无埋点...

  • iOS无痕埋点方案分享探究

    iOS无痕埋点方案分享探究 iOS无痕埋点方案分享探究

  • 为什么需要数据埋点?

    一、什么是埋点? 数据埋点我们可以分成:页面统计、行为统计、用户属性统计等。 页面统计可以帮我们知晓某个页面被多少...

  • 如何做好数据埋点

    一、埋点技术 代码埋点: 所谓的代码埋点就是在你需要统计数据的地方植入N行代码,统计用户的关键行为。比如你想统计首...

  • ios -无埋点用户行为数据收集

    数据采集 uiviewcontroller的生命周期,用于测算页面停留时间加载时间等 1.viewDidAppea...

  • iOS无侵入埋点方案

    在iOS项目开发中,我们要收集用户的行为信息以便对项目进行分析统计,就需要在代码中进行埋点统计。 一、通常的埋点方...

  • 数据分析工具GrowingIO

    新一代用户行为数据分析工具,通过无埋点数据采集技术获取全量的用户行为数据,支持web、iOS、Android、微信...

  • 关于埋点文档的一点总结

    一. 埋点的目的 埋点就是在用户使用产品时记录下用户行为数据,以便后面对用户行为进行数据分析。比如说需要页面的浏览...

网友评论

    本文标题:iOS - 无痕埋点+数据统计+记录用户行为轨迹

    本文链接:https://www.haomeiwen.com/subject/bstieqtx.html