一起养成写作习气!这是我参加「日新计划 4 月更文挑战」的第22天,点击检查活动详情。

Target-Action规划形式

在详细介绍如何完成之前,咱们需求先了解在UIKit框架下点击或拖动 事情的Target-Action规划形式。
Target-Action形式首要包括两个部分。

  • Target(目标):接纳音讯的目标。
  • Action(办法):用于表明需求调用的办法

Target可所以任意类型的目标。但是在iOS应用程序中,通常情况下会 是一个控制器,而触发事情的目标和接纳音讯的目标(Target)相同,也可 所以任意类型的目标。例如,手势辨认器UIGestureRecognizer就能够在识 别到手势后,将音讯发送给另一个目标。

当咱们为一个控件增加Target-Action后,控件又是如何找到Target并执 行对应的Action的呢?

UIControl类中有一个办法:
- (void)sendAction:(SEL)action to:(nullable id)target forEvent:(nullable UIEvent *)event;

用户操作控件(比如点击)时,首要会调用这个办法,并将事情转发 给应用程序的UIApplication目标。

同时,在UIApplication类中也有一个类似的实例办法:
- (BOOL)sendAction:(SEL)action to:(nullable id)target from:(nullable id)sender forEvent:(nullable UIEvent *)event;

如果Target不为nil,应用程序会让该目标调用对应的办法响应事情;如果Targetnil,应用程序会在响应链中搜索定义了该办法的目标,然后 履行该办法。

基于Target-Action规划形式,有两种计划能够完成$AppClick事情的全埋点。下面咱们将逐个进行介绍。

计划一

描述

经过Target-Action规划形式可知,在履行Action之前,会先后经过控件 和UIApplication目标发送事情相关的信息。因此,咱们能够经过Method Swizzling交流UIApplication类中的-sendAction:to:from:forEvent:办法,然后 在交流后的办法中触发$AppClick事情,并依据targetsender收集相关特点,完成$AppClick事情的全埋点。

代码完成

新建一个UIApplication的分类

+ (void)load {
    [UIApplication sensorsdata_swizzleMethod:@selector(sendAction:to:from:forEvent:) withMethod:@selector(CountData_sendAction:to:from:forEvent:)];
}
- (BOOL)CountData_sendAction:(SEL)action to:(id)target from:(id)sender forEvent:(UIEvent *)event {
    [[SensorsAnalyticsSDK sharedInstance] track:@"$appclick" properties:nil];
    return  [self CountData_sendAction:action to:target from:sender forEvent:event];
}

一般情况下,关于一个控件的点击事情,咱们至少还需求收集如下信息(特点):

  • 控件类型($element_type
  • 控件上显示的文本($element_content
  • 控件所属页面($screen_name

获取控件类型

先为你介绍一下NSObject目标的承继关系图

iOS 全埋点-控件点击事件

从上图能够看出,控件都是承继于UIView,所以获取要想获取控件类型,能够声明UIView的分类

新建UIView的分类(UIView+TypeData)

UIView+TypeData.h

#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIView (TypeData)
@property (nonatomic,copy,readonly) NSString *elementType;
@end
NS_ASSUME_NONNULL_END

UIView+TypeData.m

#import "UIView+TypeData.h"
@implementation UIView (TypeData)
- (NSString *)elementType {
    return  NSStringFromClass([self class]);
}
@end

获取控件类型的埋点完成

+ (void)load {
    [UIApplication sensorsdata_swizzleMethod:@selector(sendAction:to:from:forEvent:) withMethod:@selector(CountData_sendAction:to:from:forEvent:)];
}
- (BOOL)CountData_sendAction:(SEL)action to:(id)target from:(id)sender forEvent:(UIEvent *)event {
    UIView *view = (UIView *)sender;
    NSMutableDictionary *prams = [[NSMutableDictionary alloc]init];
    //获取控件类型
    prams[@"$elementtype"] = view.elementType;
    [[SensorsAnalyticsSDK sharedInstance] track:@"$appclick" properties:prams];
    return  [self CountData_sendAction:action to:target from:sender forEvent:event];
}