zoukankan      html  css  js  c++  java
  • 第47月第21天 iOS 无痕埋点解决方案

    1.

    生成 Target-Action 埋点的唯一 ID

    Target-Action 是手势和 UIControl 的回调,一般使用如下代码

    1. -[UIControl addTarget:action:events:]
    2. -[UIGestureRecognizer initWithTarget:action:]

    我们 hook 了 -[UIControl addTarget:action:events:] 方法,创建了一个 Action 对象作为附属对象,和实际的 target 一同添加到 UIControl 中。当 UIControl 触发了事件,就会同时向业务对象和 Action 对象发送消息,从而产生埋点。故我们可以在 -[UIControl addTarget:action:events:] 方法中获取到 target、action、event。还能从 -[Action action:] 方法中获取实时埋点数据。

    采集

    -[UIControl addTarget:action:events:]

    在此方法中,我们可以获取到 UIControl 类名,target 对象,action 方法名,events 事件名。由于后三个数据在下面的方法中无法获取,所以会记录后三个数据到 Action 对象中,供 Action 对象在触发下面的方法时获取对应数据:

    //  In UIControl+Hook.m
    
    - (void)hook_addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)events {
    
        // Call origin method
        [self hook_addTarget:target action:action forControlEvents:events];
        
        //  Create Action object
        MyTargetAction *action = [[MyTargetAction alloc] init];
        action.targetName = NSStringFromClass([target class]);
        action.action = NSStringFromSelector(action);
        action.events = events;
    
        // Add Action object
        [self hook_addTarget:action action:@selector(action:) forControlEvents:events];
    }
    
    

    -[Action action:]

    此方法是实际埋点执行的方法,由于此方法只能获取 self(Action 对象)和 sender(UIControl 对象),故实际埋点数据还是依赖前一个方法临时保存的数据。

    此时我们可以在方法中构成埋点数据。

    • self(Action 对象)
    • sender(UIControl 对象)
      • VC(可以根据 UIControl 获取所在 VC)
    • self.targetName(target 类名)
    • self.action(action 方法名)
    • self.events(events 值)

    拼接事件

    Action 对象

    此对象是 SDK 内部对象,无任何信息

    sender

    控件对象,大部分按钮不会继承,所以也不会有信息。

    self.targetName

    响应者类名,此类一般为 VC 的类名,或者某个 View 的类名,故此信息可用于拼接。

    self.action

    响应方法名,于前一个相同,但不同事件一般会有不同方法回调,所以方法名也可以作为唯一事件 ID。

    self.events

    事件类型,不同控件不同事件,但按钮基本为 UIControlEventsTouchUpInside,如果要区分不同控件则可以加入,本文只考虑按钮情况。故不加入此信息

    最终事件 ID 如下:

    VCClassName#TargetClassName#ActionName

    //  In MyTargetAction.m
    
    - (void)action:(UIControl *)sender {
        NSString *event_code = ({
            NSString *viewController = ({
                UIResponder *responder = sender;
                while (responder) {
                    responder = responder.nextResponder;
                    if ([responder isKindOfClass:[UIViewController class]]) {
                        break;
                    } else if ([responder isKindeOfClass:[UIWindow class]]) {
                        break;
                    }
                }
                NSStringFromClass([responder class]);
            });
            [NSString stringWithFormat:@"%@#%@#%@", viewController, self.targetName, self.actionName];
        });
            
        [Tracker trackEvent:event_code];
    }
    

    举例:

    UIViewController#UIViewController#onClick:

    UIViewController#MenuItemCell#onClickAdd:




    https://www.jianshu.com/p/f3d5e7beca23

  • 相关阅读:
    【Java】IO流--文件夹的复制
    【Java】IO流--序列化与反序列化
    【Java】Java中的数组是对象吗?(转载)
    【Java】Java漫谈-数组(转载)
    【Java】IO流--对象流--ObjectInputStream、ObjectOutputStream
    【Java】IO流--数据流--DataInputStream、DataOutputStream
    【Java】IO流--打印流--PrintStream
    【Java】IO流--转换流--InpuStreamReader、OutputStreamWriter
    CentOS快速安装Nginx的方法,nginx如何启动重启停止
    Mac查看端口号是否被占用及释放
  • 原文地址:https://www.cnblogs.com/javastart/p/13542272.html
Copyright © 2011-2022 走看看