iOS全埋点解决方案-手势采集
前言
随着科技以及业务的发展,手势的应用也越来越普及,因此对于数据采集,我们要考虑如果通过全埋点来实现手势的采集。
一、手势识别器
苹果为了降低开发者在手势事件处理方面的开发难度,定义了一个抽象类 UIGestureRecognizer 来协助开发者。UIGestureRecognizer 是具体手势识别器的抽象基类,它定义了一组可以为所有具体手势识别器配置的常见行为。它还可以通过设置委托(即实现了 UIGestureRecognizerDelegate 协议的对象),来支持对某些行为进行更细粒度的定制。
手势识别器必须被添加在一个特定的视图上(比如 UILabel、UIImageView 等控件),即需要通过调用 UIView 类中的 - addGestureRecognizer: 方法进行添加。手势识别器也是用了 Target-Action 设计模式。当我们为一个手势识别器添加一个或者多个 Target-Action 后,在视图上进行触摸操作时,一旦系统识别了该手势,就会向所有的 Target 对象发送消息,并执行 Action 方法。虽然手势识别器和 UIControl 类一样,都是使用了 Target-Action 设计模式,但是手势识别器并不会将消息交由 UIApplication 对象来进行发送。因此,我们无法使用与 UIControl 控件相同的处理方式,即通过响应者链的方式来实现对手势操作的全埋点。
由于 UIGestureRecognizer 是一个抽象基类,所以它并不会处理具体的手势。因此,对于轻拍(UITapGestureRecognizer)、长按(UILongPressGestureRecognizer)等具体的手势触摸事件,需要使用相应的子类即具体的手势识别器进行处理。
常见的具体手势识别器有:
- UITapGestureRecognizer:轻拍手势
- UILongPressGestureRecognizer:长按手势
- UIPinchGestureRecognizer:捏合(缩放)手势
- UIRotationGestureRecognizer:旋转手势
- UISwipeGestureRecognizer:轻扫手势
- UIPanGestureRecognizer:平移手势
- UIScreenEdgePanGestureRecognizer:屏幕边缘平移手势
给上面所有的具体手势识别器添加 Target-Action 的方法都是相同的,常见的主要是通过以下的两个方法进行添加。
initWithTarget:target action:
addTarget:action:
详细的定义参考如下:
/**
指定初始化方法 通过添加一个 Target-Action 进行初始化,
当初始化的手势识别器对象,识别到触摸手势时,会向 Target 对象发送消息,即调用 Action 方法 @param target 需要发送消息的 Target 对象
@param action 向 Target 对象发送的消息,即方法名
@return 初始化的对象
*/
- (instancetype)initWithTarget:(nullable id)target action:(nullable SEL)action NS_DESIGNATED_INITIALIZER; /**
向一个手势识别器添加一个 Target-Action 可以多次调用此方法,给一个手势识别器对象添加多个 Target-Action 。
如果已经添加了一个 Target-Action,再次添加相同的 Target-Action 时,会被忽略。 @param target 需要发送消息的 Target 对象
@param action 向 Target 对象发送的消息,即方法名
*/
- (void)addTarget:(id)target action:(SEL)action;
在实际的开发过程中,使用比较多的是 UITapGestureRecognizer 和 UILongPressGestureRecognizer 两个手势识别器,这两个手势识别器分别是处理轻拍手势和长按手势。
二、手势全埋点
在数据采集中,一般只需要采集常见控件(UILabel、UIImageView)的轻拍和长按手势。
所以,我们分别介绍如何实现控件轻拍和长按手势的全埋点。
2.1 UITapGestureRecognizer 全埋点
为了采集控件的轻拍手势,我们可以通过 Method Swizzling 交换 UITapGestureRecognizer 类的添加 Target-Action 的方法,从而可以添加一个新的 Target-Action,并在新添加的 Action 方法中触发 $AppClick 事件,从而就可以达到采集控件轻拍手势全埋点的效果。
在 UITapGestureRecognizer 类中,用于添加 Target-Action 方法有两个:
• - initWithTarget:action:
• - addTarget:action:
因此,我们需要对这两个方法分别进行交换。
第一步:创建 UITapGestureRecognizer 分类 UIGestureRecognizer+SensorsData,并实现 +load 类方法,在 + load方法中,进行 - initWithTarget:action: 和 - addTarget:action: 的方法交换。
#import "UIGestureRecognizer+SensorsData.h"
#import "NSObject+SASwizzler.h"
#import "SensorsAnalyticsSDK+Track.h"
@implementation UITapGestureRecognizer (SensorsData)
+ (void)load {
[UITapGestureRecognizer sensorsdata_swizzleMethod:@selector(sensorsdata_initWithTarget:action:) withMethod:@selector(initWithTarget:action:)];
[UITapGestureRecognizer sensorsdata_swizzleMethod:@selector(addTarget:action:) withMethod:@selector(sensorsdata_addTarget:action:)];
}
- (instancetype)sensorsdata_initWithTarget:(id)target action:(SEL)action {
[self sensorsdata_initWithTarget:target action:action];
[self addTarget:target action:action];
return self;
}
- (void)sensorsdata_addTarget:(id)target action:(SEL)action {
[self sensorsdata_addTarget:target action:action];
// 新增 Target-Action, 用于触发 $AppClick 事件
[self sensorsdata_addTarget:self action:@selector(sensorsdata_trackTapGestureAction:)];
}
- (void)sensorsdata_trackTapGestureAction:(UITapGestureRecognizer *)sender {
[[SensorsAnalyticsSDK sharedInstance] trackAppClickWithView:view properties:nil];
}
第二步:在 - sensorsdata_trackTapGestureAction: 方法中判断要采集的控件
- (void)sensorsdata_trackTapGestureAction:(UITapGestureRecognizer *)sender {
UIView *view = sender.view;
// 暂定只采集 UILabel 和 UIImageView
BOOL isTrackClass = [view isKindOfClass:UILabel.class] || [view isKindOfClass:UIImageView.class];
if (!isTrackClass) {
return;
}
[[SensorsAnalyticsSDK sharedInstance] trackAppClickWithView:view properties:nil];
}
第三步:测试验证
{
"event" : "$AppClick",
"time" : 1648892963385,
"propeerties" : {
"$model" : "x86_64",
"$manufacturer" : "Apple",
"$element_type" : "UIImageView",
"$lib_version" : "1.0.0",
"$os" : "iOS",
"$app_version" : "1.0",
"$screen_name" : "ViewController",
"$os_version" : "15.2",
"$lib" : "iOS"
}
}
2.2 UILongPressGestureRecognizer 全埋点
对于 UILongPressGestureRecognizer 来说,其实现逻辑与 UITapGestureRecognizer 基本上是相同的。
iOS全埋点解决方案-手势采集的更多相关文章
- iOS全埋点解决方案-采集奔溃
前言 采集应用程序奔溃信息,主要分为以下两种场景: NSException 异常 Unix 信号异常 一.NSException 异常 NSException 异常是 Objectiv ...
- iOS全埋点解决方案-控件点击事件
前言 我们主要介绍如何实现控件点击事件($AppClick)的全埋点.在介绍如何实现之前,我们需要先了解一下,在 UIKit 框架下,处理点击或拖动事件的 Target-Action 设计模式. ...
- iOS全埋点解决方案-UITableView和UICollectionView点击事件
前言 在 $AppClick 事件采集中,还有两个比较特殊的控件: UITableView •UICollectionView 这两个控件的点击事件,一般指的是点击 UITableViewCell 和 ...
- iOS全埋点解决方案-应用退出和启动
前言 通过应用程序退出事件,可以分析应用程序的平均使用时长:通过应用程序的启动事件,可以分析日活和新增.我们可以通过全埋点方式 SDK 实现应用程序的退出和启动事件. 一.全埋点的简介 目前. ...
- iOS全埋点解决方案-界面预览事件
前言 我们先了解 UIViewController 生命周期相关的内容和 iOS 的"黑魔法" Method Swizzling.然后再了解页面浏览事件($AppViewScr ...
- iOS全埋点解决方案-时间相关
前言 我们使用"事件模型( Event 模型)"来描述用户的各种行为,事件模型包括事件( Event )和用户( User )两个核心实体.我们在描述用户行为时,往往只需要描述 ...
- iOS全埋点解决方案-数据存储
前言 SDK 需要把事件数据缓冲到本地,待符合一定策略再去同步数据. 一.数据存储策略 在 iOS 应用程序中,从 "数据缓冲在哪里" 这个纬度看,缓冲一般分两种类型. 内 ...
- iOS全埋点解决方案-APP和H5打通
前言 所谓的 APP 和 H5 打通,是指 H5 集成 JavaScript 数据采集 SDK 后,H5 触发的事件不直接同步给服务器,而是先发给 APP 端的数据采集 SDK,经过 APP 端数 ...
- iOS 全屏侧滑/UIScrollView/UISlider间滑动冲突
代码地址如下:http://www.demodashi.com/demo/13848.html 效果预览 一.前期准备 有一个支持全屏侧滑返回的视图控制器ViewController,ViewCont ...
随机推荐
- XML约束DTD
<元素1> <元素2> <元素3>描述1</元素3> <元素4>描述2</元素4> </元素2> </元素1& ...
- 如何在 Spring Boot 中禁用 Actuator 端点安全性?
默认情况下,所有敏感的 HTTP 端点都是安全的,只有具有 ACTUATOR 角色的用户才能访问它们.安全性是使用标准的 HttpServletRequest.isUserInRole 方法实施的. ...
- RabbitMQ 的集群?
镜像集群模式 你创建的 queue,无论元数据还是 queue 里的消息都会存在于多个实例上,然后 每次你写消息到 queue 的时候,都会自动把消息到多个实例的 queue 里进行消息 同步. 好处 ...
- 为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动 的区别在哪里?
Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联 集合对象时,可以根据对象关系模型直接获取,所以它是全自动的.而 Mybatis 在查询关联对象或关联集 ...
- 什么是 Spring 的依赖注入?
依赖注入,是 IOC 的一个方面,是个通常的概念,它有多种解释.这概念是说你 不用创建对象,而只需要描述它如何被创建.你不在代码里直接组装你的组件和 服务,但是要在配置文件里描述哪些组件需要哪些服务, ...
- Windows10安装PHP7+Apache 2.4
下载下面的文件 httpd-2.4.39-win64-VC15.zip php-7.3.4-Win32-VC15-x64.zip 如果下载失效,从这里下载 https://windows.php.ne ...
- 遇到的错误之"Exception in thread “main“ java.lang.NoClassDefFoundError: org/apache/velocity/context/Context at"
问题 Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/velocity/context/ ...
- 1.时任务XXL_Job框架踩过的坑
遇到的问题 问题1:执行器地址为空 原因-->执行器中 没有地址 解决方案-->输入地址:http://IP地址:端口 IP地址 端口 问题2:异常信息unknown code for r ...
- STM32 HAL库与标准库的区别_浅谈句柄、MSP函数、Callback函数
最近笔者开始学习STM32的HAL库,由于以前一直用标准库进行开发,于是发现了HAL库几点好玩的地方,在此分享. 1.句柄在STM32的标准库中,假设我们要初始化一个外设(这里以USART为例)我们首 ...
- HTML5与HTML4区别简介
移动互联网的快速发展,尤其是4G时代已经来临,加上微软在Windows 10中搭载了新的浏览器Edge取代了IE的地位,所以现在很多网站都开始抛弃IE朝着HTML5发展,PC端在不同浏览器之间的兼容性 ...