网易HubbleData无埋点SDK在iOS端的计划与贯彻

0 引言

近来在当店之HubbleData的埋点SDK的出任务,产品之雏形其实在几乎年前就曾经来矣,公司间的例如考拉、易信、LOFTER、美学、漫画等大多款产品还早已搭使用。

生图为出HubbleData SDK某个应用之片分析的显示页面:

(1)概览示意图

事件

(2)事件分析示意图

事件

(3)实时分析示意图

事件

除此以外HubbleData平台尚享有在分析、漏斗分析、粘性分析、数据看板等多种力量,方便有关负责人员对成品用户作为开展更进一步的探讨分析。

直版本的SDK的计划性是代码埋点实现的,虽然于部分比较成熟之出品,代码埋点完全能上产品在的急需,但是对于片初启动要用数变动的要求的初产品等,考虑到那个保护的基金大,代价高等缺点,HubbleData无埋点SDK的统筹虽显示更重大了。

自身根本承担iOS端无埋点以及可视化圈选的干活,文章主要系讲授一下HubbleData无埋点SDK在iOS端的统筹及落实与一些系问题之解决,后续将针对所有埋点的兑现流程与可视化圈选等内容又发作分享。

相同、埋点简介

1.1 三种植埋点的贯彻方式简介

埋点的艺术分为三类:代码埋点、可视化埋点和无埋点。这里大概的牵线一下老三种植埋点方式:

(1)
代码埋点即凡以代码的关键部位植入所假设搜集数据的N行代码,需要挖掘起产品我,深入了解产品的事体逻辑和项目组织,下面代码模拟显示的即凡是点击提交订单的上HubbleData
SDK代码埋点;

代码埋点示例

(2)
可视化埋点即用可视化交互的点子圈选出所设募数据的控件,当用户作为发生时,即可收集到对应的埋点数据。相比叫前的代码埋点而言,可视化埋点能够化解代码埋点代价十分本大之问题,但是无法活的自定义埋点属性。

可视化埋点流程

(3)
无埋点也让全埋点,即未需要用户积极埋点,可以搜集用户拥有的操作行为,同样以可视化圈选,用户会以到所想征集的埋点数据,能够缓解可视化圈选中多少不可回溯的题目。下图被闹了不管埋点数量搜集之简练流程。

无埋点数据搜集流程

HubbleData
SDK的计划要是代码埋点结合无埋点的数码搜集方式,其中为涉到可视化埋点被之屏幕序列化及波绑定机制,本文主要介绍一下无埋点的计划性和落实。

1.2 无埋点SDK设计详细流程

产图让出HubbleData无埋点SDK在iOS端的设计实现:

无论埋点详细计划流程

起上图可以看来,HubbleData的无埋点是于代码埋点的功底及贯彻之,所处任埋点的难处也便集中在以下三独面:

(1)自动获取埋点的EventID
(2)自动获取埋点的时机
(3)自动获取埋点需采集的属性

正文主要就即刻三独面展开解析,第二有关键谈一下波唯一ID的确定,第三片至关重要出口一下无埋点的采的落实,主要是各种风波闹采集的机会和需要采集的性能的布。

HubbleData
SDK还涉嫌到博另力量,包括屏幕序列可视化、代码埋点、精准渠道追踪等,这里不再介绍,后面会陆续分享相关的技巧实现。

次、事件唯一ID的规定

为实现以可视化圈选的常的事件的唯一性,每一个无埋点的风波采访都必须发且仅来一个唯一的标识符来区分不同之风波。不同让代码埋点,用户可以起定义之布置好所需要的EventID,无埋点过程中,需要SDK自己安排各级一个采访事件之EventID,通过可视化圈选的操作,筛选产生相应的EventID所对应之数目信息。HubbleData采用的是布局view唯一标识字符串的法去唯一的标识这样的一个轩然大波,主要出于view的层级结构path路径、该view的到处页面类名以及view所带的组成部分自定位属性等组成,并通过SHA256编码来博取唯一的EventID。

脚将一体化系统介绍部分波唯一ID的成形过程。

2.1 控件的层级结构path构造

2.1.1 普通view的层级结构path构造

层级结构path主要是基于页面的控件树构造而成为,每个view都有superview与subviews的性质,将各一个view的superview作为培养的父节点,将那个subviews作为子节点,这样就会管方方面面app上之所有view组成一株大的控件树,其中树之顶层是UIWindow,然后是各国一个view节点依次向下展开。下图被起一个粗略的控件树的组织图。

空中树结构

脚会详细介绍一下HubbleData的绝无仅有标识路径的组织方式。

不同类

同类

如及图1所展示,如果一个view的subviews中都是殊品种的,比如像下图图1所展示之控件树那样,可以唯一标识UILabel和UIButton控件为:

UIView_UILabel
UIView_UIButton

但是诚的页面是免会见像美被的有控件都是殊类别的,可以说这种太气象基本不存,如果还是以上述的法门来布局路径的语句,两个UILabel都见面受标识成UIView_UILabel,这分明无法区分两个控件。因此只有是每个控件节点的门路名称是心有余而力不足唯一标识是控件的,这里HubbleData加入了这个控件节点在父视图中的index。比如达图2,可以拿少独UILabel标识也:

UIView(0)_UILabel(0)
UIView(0)_UILabel(1)

此地要父视图是index为0的一个节点,这样便得完全的界别出点儿单控件了。

那余下的问题便是每个UIView index索引值的确定。

每个UIView都生subviews属性,每一个子视图都起一个被addsubView的次,其实要用的斯index就是子视图被add的次序,那么该怎么用到这个程序呢,在苹果之官认证文档中,岁UIView的subviews属性,是这般介绍的:

@property(nonatomic, readonly, copy) NSArray *subviews

You can use this property to retrieve the subviews associated with your custom view hierarchies. 
The order of the subviews in the array reflects their visible order on the screen.

不畏各级一个子视图在此subviews数组中的目就是HubbleData要将的index。

针对复杂的视图形式,如下图所出示,按照上述的层级结构路径构造方法得到的绝无仅有层级路径为:

UIView(0)_UILabel(0)
UIView(0)_UIButton(1)
UIView(0)_UIButton(2)  

混合

自上述的解析会,按照上述介绍的艺术开展view的唯一层级路径标识,对绝大多数底页面来说都足够,但是对于部分一发灵活点的页面,由于有的业务要求等原因,开发人员经常会调用removeFromSuperview,
insertSubview:atIndex:, insertSubview:
belowSubview:等函数,都见面大的影响整页面的subviews的索引值,比如现在本人以高达图所展示之UILabel移动至少独UIButton的后面,那么得的唯一层级路径为:

UIView(0)_UIButton(0)
UIView(0)_UIButton(1)
UIView(0)_UILabel(2)  

混合

得发现,唯一层级路径都深受反,但是任何页面也尚未发生变化,不仅会起新的事件(比如UIButton(0),UILabel(2)),连UIButton(1)事件的征集也会拧,即使是例外的风波,却得到了不同的eventID,所以待增强组织之层级结构路径的稳健型。

刚巧像刚刚提到的,不同品类的UIView不欲开index的别,那么以收获之index的时,不是略的自subviews这个数组中得到其相应的索引值,而是进行一个简易的同类归并还取索引值,一个雅粗略的拍卖。

for (UIView *view in subviews) {
    if ([NSStringFromClass([subview class]) isEqualToString:NSStringFromClass(class)]) { //class为待筛选的类
        [array addObject:view];
    }
}

诸如此类虽可收获array中的index作为那个真正的索引值,得到的层级结构路径也:

UIView(0)_UILabel(0)
UIView(0)_UIButton(0)
UIView(0)_UIButton(1) 

这时无论UIlabel的职放在哪儿,都非见面转者途径的布局样式,大大加了稳健型。其实也能觉察,这只有只能加强稳健型,并无可知从根本上解决者问题,比如要自己把个别只UIButton的次第调换了,或者去除了第一个,此时照旧会赢得有休可靠之层级路径。此题材会见延续解决,会日益引入误差容量和相似度这个定义,即如以误差范围外,则会展开进一步的相当,具体的解决方案本篇不以介绍。

2.1.2 几栽特有情况的处理

2.1.1主要讲的凡有的习以为常view的层级结构的path构造方式,但是发生局部特情况需要特地之设想处理:

  • UITableViewCell

是因为UITableViewCell具有可复用的建制,当一个页面被当不断滚动的上,cell在不停的复用,如果还采取2.1.1负介绍的方法来得到index索引值话,那么会挑起上上下下页面无埋点数据收集的繁杂。

当得到当前UITableViewCell的index时,可以利用indexPath参数进行调换,这个参数可精确的收获section和row的值,唯一的附和每一个cell。唯一层级路径的款式得以由定义配置,HubbleData的安装方法啊:类名+(section:
row:),下面给有一个演示:

MyTableViewCell(section:0 row:7)
  • UICollectionViewCell

UICollectionViewCell的path生成原理与UITableViewCell,HubbleData的安装方法啊:类名+(section:item:),下面被有一个演示:

MyCollectionViewCell(section:0 item:7)
  • UIControl

其实UIButton也毕竟一种植家常view的平种,大多数景象下,使用上述的层级结构path以及页面类名的组合会唯一的规定当前UIControl的绝无仅有标识符,但是来同样种异常的状况,当当UINavigationItem时见面冒出特别情形,下面的所被出之一定量独例证。

bar1

bar2

当点击第一只NavigationBar的右侧的按钮时,得到的层级路径为:

...UIViewControllerWrapperView(0)_UIView(0)_UILayoutContainerView(0)_UINavigationBar(0)_UIButton(1)

浅析会,左侧的装按钮的目为0,所以右侧的按钮索引为1。同时得到之脚下页面吗:UINavigationController。

当点击第二单页面的同一个列的按钮时,即一律标明出数字7的item时,此时获取的层级路径也:

...UIViewControllerWrapperView(0)_UIView(0)_UILayoutContainerView(0)_UINavigationBar(0)_UIButton(2)

好发现这底按钮的目变成了2,已经不同为上述第一个NavigationBar的和一个按钮的层级路径了,经过分析,索引值为1底按钮是无限右侧的表格的好item,经过认证可以博其层级路径:

...UIViewControllerWrapperView(0)_UIView(0)_UILayoutContainerView(0)_UINavigationBar(0)_UIButton(1)

取之页面也:UINavigationController。

实际这种页面很普遍,由于页面的切换,NavigationBar上之有些按钮的职位或顺序会打乱,导致同一个职能的NavigationItem已经黔驴技穷确定标识唯一,即使是获取了眼前按钮所当的页面吗束手无策区分,因为落之都是UINavigationController。从点的解析好见见,这种情况竟然会见招致惨重混乱的数收集。

实际上仔细分析一下,如果条分缕析得出该UIControl是当UINavigationBar上,则无需安装其相应的index值,即上述的有着navigationItem的层级结构路径都也:

...UIViewControllerWrapperView(0)_UIView(0)_UILayoutContainerView(0)_UINavigationBar(0)_UIButton

不畏都不举行区分。

HubbleData采用增加一种植新的性能来区别各个item,其实特别明白可以关押出来,这个item的行之action肯定是不同之,所以取其action属性来区别,最终的别形式如下:

path(...UIViewControllerWrapperView(0)_UIView(0)_UILayoutContainerView(0)_UINavigationBar(0)_UIButton)&actions(button1Click:)
path(...UIViewControllerWrapperView(0)_UIView(0)_UILayoutContainerView(0)_UINavigationBar(0)_UIButton)&actions(button2Click:)

这般,HubbleData就可以精确的分别不同之item了,同时落实平等种效应的item,由于其action相同,所以呢会见准确的标识其唯一性。

  • UIAlertController

是因为不同之UIAlertController在选择确定、取消当选择时,选取的进展唯一层级路径判定的view需要进行得之拍卖,同时为保险不同之UIAlertController处于同一职务的选项的埋点EventID不同,这里当布局唯一标志字符串的当儿还要在该UIAlertController的message和title信息。3.5小节中见面展开相关无埋点采集的牵线。

  • viewController的嵌套

诚如情况下,普通的view只需要遵循一般的层系路径收集index即可,但是当在pageViewController时,如下图所显示分别叫闹了一个横向滚动(以店堂考拉app为条例)和纵向滚动(以商店严选app为条例)的app的截图的以身作则:

事实上可以见到,pageViewController会应用至繁app中,所以这类似app在动过程中之无埋点问题愈加要考虑。

(1) 各个子页面的controller不同?

假设pageViewController中之相继子页面不同,虽然累2.2节HubbleData会在页面controller的音来分别这些不同的子页面,但是或许会见由每个子页面加入的次第不同,导致每次app进来的当儿和一个页面的波会获得不同之EventID,举例来说明一下,如齐图1所展示,比如前面四独子页面是ViewController1,
ViewController2, ViewController3,
ViewController4,这类pageViewController除非设置四只子页面同时预加载出来,那么这之落的层级路径也:

ViewController1对应路径为:superview(0)_subControllerView(0) 
ViewController2对应路径为:superview(0)_subControllerView(1)
ViewController3对应路径为:superview(0)_subControllerView(2)
ViewController4对应路径为:superview(0)_subControllerView(3)

但是app基本都不见面预加载出有页面,对于用户不感兴趣的页面完全没必要一次性全部加载处理,只有当用户挑选了该条目时,该对应的子页面才见面加载出来,如果今天用户点击的逐一是ViewController1,ViewController3,ViewController4,ViewController2,由于addChildViewController或者addSubView的各个的改变,那么此时赢得之层级路径为:

ViewController1对应路径为:superview(0)_subControllerView(0) 
ViewController2对应路径为:superview(0)_subControllerView(3)
ViewController3对应路径为:superview(0)_subControllerView(1)
ViewController4对应路径为:superview(0)_subControllerView(2)

足发现,index值变了,层级路径不唯了,那么不论埋点采集的EventID可能会见由用户挑选页面顺序的不比而各异,造成埋点数据的混乱。

HubbleData对于此类页面的处理是,遇到此类页面,即非用index标注,所以会见合并的标识成:

ViewController1对应路径为:superview(0)_subControllerView 
ViewController2对应路径为:superview(0)_subControllerView
ViewController3对应路径为:superview(0)_subControllerView
ViewController4对应路径为:superview(0)_subControllerView

此起彼伏可以透过不同之页面的controller的类名获取其不同的绝无仅有标识字符串。

(2) 各个子页面的controller相同?

其实开了此类页面的中心应该还如数家珍,很多情景下子页面都是公家的,只不过是填的model不同而已,那么遇到这种景象,如果是仍问题1的解决思路,即使以2.2用到了现阶段页面的controller,那么要无法区分出这些页面,所以要待装新的装有辨识度的index。

实则通过pageViewController可以发现,用户可以通过左右滑或者前后滑动来切换子页面,说明拥有的子页面都是放到在一个scrollView之中,那么就是可打夫scrollView入手,重新规定index。下面让出HubbleData解决者问题的艺术。

同等开始想念利用时scrollView的contentOffset整除了这pageViewController的页面宽度与惊人所得到的值作为区分子页面的index,但是考虑到或contentOffset的连天变与子页面横跨pageViewController整数倍宽度的边际时,可能会见导致获取的index不唯一的情状,所以后来应用该子页面的原初位置整除pageViewController的附和地宽度与冲天得到相应地index。具体的兑现如下,其中controller为当前底页面:

 if (view == controller.view || view == controller.view.superview) {
      NSInteger index_x = view.center.x / [view superview].frame.size.width;
      NSInteger index_y = view.center.y / [view superview].frame.size.height;
      NSString *path = [NSString stringWithFormat:@"%@(indexx:%ld indexy:%ld)",  
                        NSStringFromClass([view class]), index_x, index_y];
  } 

就此同样对上述(1)所给闹的季独ViewController1,优化后底至的唯一的标识也:

ViewController1对应路径为:superview(0)_subControllerView(indexx:0 indexy:0)
ViewController2对应路径为:superview(0)_subControllerView(indexx:1 indexy:0)
ViewController3对应路径为:superview(0)_subControllerView(indexx:2 indexy:0)
ViewController4对应路径为:superview(0)_subControllerView(indexx:3 indexy:0)

如此这般即使各个子页面的controller相同,也能经过优化后的index来分别各个不同之子页面。当然这种唯有是针对性嵌套scrollView的子页面的景,不过能化解大部分的此类问题,对于一些其他的异样状况等,需详细分析页面布局进行剖析。

2.2 当前页面controller的拿走

看上去,大多数情下2.1之view的层级结构path已经基本确定view的唯一标识字符串,但是普遍存在这么一种情形,当同一个页面跳反两只不同之页面时,假如这点儿个例外之页面上还取第一只按钮的层级路径,得到的简化后底结果尚且如下所示:

.../UINavigationTransitionView(0)/UIViewControllerWrapperView(0)/UIView(0)/UIButton(0)

是无能为力开展及时简单个页面及的按钮区分的,其实页面的类名是分的一个顶直白的办法。HubbleData是本下面的点子取得有view所在的controller的类名的。

获得当前controller示例

以view的层级路径结合当下页面的称,已经能化解掉大部分底唯一标识字符串的题材了。

此地用小心的某些凡是,当页面类型一样,只是填充的model不以,比如浏览商品详情时,所进入的页面还是一个,只是model不同,目前HubbleData对这种状况少无开处理。后续可参考文章3.2节UIViewController的无埋点采集,对有页面,用户可以由定义诸如screenTitle的字段,定义该页面的名目,比如screenTitle包含产品唯一ID时,此时用拖欠字段加入唯一标识字符串中即可区分。目前这块还免做相关处理,这里只是供一个简的化解思路。

>三、无埋点的采集的实现

3.1 AOP 简介

下面说一下无埋点的有血有肉实现,用到的机要是AOP(Aspect-Oriented-Programming),面向切面编程,面对的是处理过程中之有步骤同办法。在运作时,动态的以代码插入到接近的制定措施、指定位置上的编程思想就是是面向切面编程。熟悉iOS
Runtime的应怪亮,相关的介绍文章也杀多,这里不再过多的废话。

HubbleData无埋点的实现主要就是借助AOP,hook对应类的主意,并当原本实现代码的底蕴及插自己定义的埋点的代码,当该类的给hook的函数执行时,就可知促成无埋点数据收集的功能。下面让出HubbleData里面Method
Swizzling的一个略的贯彻。

Method Swizzling

上述代码只是被起了一个简约的兑现的逻辑结构,new_swizzledMethod也无非是selector没有参数的场面(除去self和_cmd),真正当埋点的处理过程需要考虑的景象比多。

3.2 UIViewController的无埋点采集

重中之重是采访页面的生命周期,这里HubbleData采用的是hook
UIViewController的viewWillAppear方法,按照3.1于起的方法:

 [DASwizzler swizzleBoolSelector:@selector(viewWillAppear:)
                         onClass:[UIViewController class]
                       withBlock:executeAppearBlock];

当viewWillAppear函数执行时,插入埋点的代码。HubbleData的宏图方式也:

EventID设置为稳定的da_screen,即无会见透过EventID来分各个页面的音信,HubbleData将各个页面的分别信息在了properties中,其中properties的安为:

(1) $screenName 为当前页面的名称;
(2) $screenTitle 为当前页面的title,可为空;

还要HubbleData SDK提供了一个protocol <DAScreenAutoTracker>

便用户可以经落实该protocol,HubbleData
SDK会将screenTitle返回的价作为页面的号,trackProperties返回的性质在对应页面的da_screen事件之属性被,作为用户访问该页面时之风波性质,screenUrl返回的字符串作为页面的Url,用于做一些页面中彼此跳转的辨析等。

以多了白名单设置,有有UIViewController的音讯用户不思量征集,可以经过设置白名单的章程,将一部分不思量征集的UIViewController过滤掉,比如说SFBrowserRemoteViewController,UIInputWindowController等系统自带的有的。

最终见面调用trackEvent记录该征集的波,同上述介绍的代码埋点一样,调用的方法如下:

[[DATracker sharedTracker] trackScreenEvent:@“da_screen” withAttributes:properties];

中间properties即为上述要采访的部分性能。

3.3 UIControl之无埋点采集

针对UIControl,HubbleData采用的是hook
UIControl的sendAction:to:forEvent:方法。由官方文档可知,在UIControl执行相应的action时犹见面率先调用sendAction真珠美学:to:forEvent:方法,实现如下:

control

考虑到UIControl的子类较多,所以HubbleData选取了中间以比较多的几乎种进行了独特的分析:主要是UITextField、UIButton和UISwitch,其余的临时性无开特殊分析。具体的埋点的采集计划呢:

任哪种UIControl,EventID均用的凡第三局部介绍的绝无仅有标识字符串的SHA256造码值,但是相关采访properties有所区别。

3.3.1 UITextField

UITextField是UIControl的一个子类,由于UITextField涉及到用户之苦比较多,比如用户称、密码、聊天文本等,所以HubbleData不见面指向此类的UITextField进行埋点的采集。

HubbleData主要收集的是UISearchBar中的UITextField,即UISearchBarTextField,并取搜索的文书内容,这对于有些电商类的App来说,能够比好的分析用户感兴趣之货品等,这是当做HubbleData
SDK无埋点的一个求。

hook住sendAction:to:forEvent:后,如果对UISearchBarTextField的所有actions都进行hook的话,那么_searchFieldBeginEditing、_searchFieldEndEditing等有着的action发生的当儿都见面展开多少的采集,会征集到许多空头的信,导致采集的数码错乱。HubbleData
SDK只有当_searchFieldEndEditing
action发生常才会进展埋点,收集的properties为:

(1) type 为UIControl采集的事件类型,这里设置为searchBarEvent;
(2) page 为当前页面的名称,用于前端显示用;
(3) searchText 为_searchFieldEndEditing发生时采集到搜索框的搜索文字(此字段不为空);

这般即使能够针对搜索框进行无埋点采集,并会募集搜索的文本内容。此办法才是在_searchFieldEndEditing发生常采访数据,有或该action执行时尚未尽兴真正的探寻操作,可能会见跟业务数据库的数码来出入,但是呢能够比较规范之辨析用户感兴趣的搜寻内容。

3.3.2 UIButton

UIControl中行使最多尽广大的凡UIButton,因此对UIButton的集很重要。在采用UIButton的时段可轻易的安装其title等性来代表事情逻辑的例外状态。这里可以推一个简的例子:基本app的记名页面,在用户称和密码都不输入时、都输入时跟登录中各个状态,登录按钮的title、titleColor等特性可能还是殊之,即每一样种植button的体制且意味着着平等栽体制,但是得的EventID是一律之。针对此种植情形,HubbleData会加盟title、titleColor作为属性值,以好后台进行更为的辨析。

当按钮的个别栽状态只有是个别种植不同之背景图片时,比如微博要微信的点赞等,其实是易了一如既往种背景图片,针对对这种景象处理,HubbleData则会取得图片的imageName作为内部一个特性。

(1) type 为UIControl采集的事件类型,这里设置为buttonEvent;
(2) page 为当前页面的名称,用于前端显示用;
(3) title 为当前按钮的title;
(4) titleColor 为当前title的color,会转换成字符串的形式,rgba(r, g, b, alpha);
(5) imageName 为当前按钮的背景图片的name;
(6) frame 为UIButton的frame,用于分析同类元素,会转换成字符串的形式,rect(x, y, width, height);

可观看,HubbleData还搜集了该view的frame信息,主要是用来分析同类元素用之,下图于来一个简练的以身作则:

button

当前起六个就关注之出品,当思统计用户所有点赞的风波频仍,由于每个点赞的按钮都远在一个UITableViewCell中,在前方介绍的博层级唯一路径UITableViewCell时的超常规处理,由于每个按钮所当的cell的row不同,所以取的每个按钮的波的唯一EventID都是差之,这样晚端在条分缕析的时段,无法归类同类元素。当HubbleData给起frame时,后端可以依据frame归类出同一近似按钮的风波,具体的分类策略这里不再介绍。

3.3.3 UISwitch

接近于UIButton,只不过这里而采访switchState,即眼前底开关状态,具体的集属性为:

(1) type 为UIControl采集的事件类型,这里设置为switchEvent;
(2) page 为当前页面的名称,用于前端显示用;
(3) switchState 为switch的开关状态;
3.3.4 其余UIControl

外的不过是采访type,page属性,目前匪开了多之拍卖。

3.4 UITableView和UICollectionView的无埋点采集

针对UITableView和UICollectionView,HubbleData采用的是先hook
UITableView和UICoolectionView的setDelegate:方法,然后找到呼应之delegate,然后再hook
delegate类中之tableView:didSelectRowAtIndexPath:方法和UICollectionView的collectionView:didSelectItemAtIndexPath:方法。这里为UITableView为条例:

tableview

EventID按照上述介绍的法子得到,只不过这里要小心的是,获取之连无是UITableView的唯一标识字符串而是对应之点击的cell的唯一标识字符串。采集的properties为:

(1) type 为UITableView采集的事件类型,这里设置为tableViewSelectEvent;
(2) page 为当前页面的名称,用于前端显示用;
(3) section 为点击的cell所在的section;
(4) row 为点击的cell所在的row;

3.5 UIGestureRecognizer的无埋点采集

于iOS开发被,经常会面采用有手势来处理局部点击的操作,所以呢闹必不可少对UIGestureRecognizer进行hook。HubbleData
并无是直指向UIGestureRecognizer这个仿佛进行hook,而是hook
UIView类的addGestureRecognizer:方法,实现如下:

gesture

经hook
addGestureRecognizer:方法,可以获取该UIView所添加的UIGestureRecognizer,这里就对UITapGestureRecognizer和UILongPressGestureRecognizer进行拍卖,其他的手势暂勿开拍卖。得到相应的UIGestureRecognizer,添加一个action,当该手势执行之时节,同样会执行该action,在action中执行埋点的操作。

此取之是UIGestureRecognizer所在的UIView的唯一标识标识字符串编码作为EventID,采集的特性为:

(1) type 为UIGestureRecognizer采集的事件类型,这里设置为gestureTapEvent;
(2) page 为当前页面的名称,用于前端显示用;

UIAlertController的奇异处理

这里需要针对UIAlertController做一个详实的征,因为UIAlertController在点击诸如取消、确定的选择项按钮时,也会展开手势的埋点采集,但是在iOS9和iOS10直达稍加有几区别。

此间先盖iOS9也条例,其target是作用在_UIAlertControllerView这个系统的私有类上之,如果直白指向这_UIAlertControllerView进行唯一标识字符串的结构,则取消同确定选项得到的EventID是同样的,这样以无法精确的分析有用户之挑选,所以要坐每个选项view作为独立的绝无仅有标识字符串进行分析才能够确切区分。通过取得_UIAlertControllerView的_actionViews变量,就可知博取各个选项的view,这里而召开一个简约的点击坐标获取,判断所点击的区域在的actionView,具体贯彻如下:

这边当原则判断时设定gesture.state ==
UIGestureRecognizerStateBegan,是出于UILongPressGestureRecognizer会连续两涂鸦调用action,因此这里要进入事件之状态进行区分,防止进行个别坏同之数搜集。

iOS10下蛋之UIAlertController的其中贯彻做了有些变动,其target变更换成在_UIAlertControllerInterfaceActionGroupView这个系统的私有类上的,然后用进行定的拍卖,获取UIInterfaceActionSelectionTrackingController的_representationViews变量,遍历得到各个选项的view,具体贯彻如下:

通过上述的辨析好窥见,这样尽管能够分别和一个UIAlertController的两样之操作选项,但是可能无法区分出不同UIAlertController的处相同位置的选项项,所以这边还要投入UIAlertController额外的习性信息来区别。

前方吧生领了,可以充分易的想到UIAlertController的message和title能够比较好之开展区分,所以当初的层级路径和当前页面的根底及,还要加上message和title以结合唯一标识字符串。给闹一个样例:

path(UIWindow(0)__UIAlertControllerView(0)_UIView(0)_UIView(0)_UIView(0)_UICollectionView(0)__UIAlertControllerCollectionViewCell(section:0 item:0)_UIView(0)__UIAlertControllerActionView(0))&controller(UIAlertController)&message(确认退出群聊吗?)&title(退群)

四、总结

文章主要介绍了HubbleData无埋点SDk在iOS端的宏图和落实,涉及的要害内容:事件唯一ID的规定与组成部分无埋点的落实,当然在无埋点SDK的规划出中尚遇上了丰富多彩的问题。鉴于文章的篇幅就比丰富,一些题目之缓解及关键技术的贯彻,比如精准渠道追踪、hook冲突解决、代码埋点的实现、屏幕序列化以及可视化圈选部分的情节,本篇文章不再介绍,将会晤以后续文章被持续介绍。