亿万先生(3)实时分析示意图,无码埋点的兑现流程

0 引言

近些年于承担公司的HubbleData的埋点SDK的开发任务,产品之雏形其实在几乎年前就是既闹矣,公司内部的诸如考拉、易信、LOFTER、美学、漫画等多款产品都已属使用。

下图被出HubbleData SDK某个应用之组成部分分析的来得页面:

(1)概览示意图

事件

(2)事件分析示意图

事件

(3)实时分析示意图

事件

其它HubbleData平台尚拥有在分析、漏斗分析、粘性分析、数据看板等强效率,方便有关负责人士针对产品用户作为开展更进一步的探索分析。

总版本的SDK的规划是代码埋点实现之,即使于部分较成熟之出品,代码埋点完全可以达成产品正的需,可是于片初启动要用数变动的需要的新产品等,考虑到该保障的本异常,代价高等缺点,HubbleData无埋点SDK的统筹虽呈现更为首要了。

自家根本负责iOS端无埋点以及可视化圈选的行事,小说重要系讲授一下HubbleData无埋点SDK在iOS端的统筹和贯彻同一部分相关问题之缓解,后续将对所有埋点的贯彻流程以及可视化圈选等情节更发分享。

亿万先生 1

同样、埋点简介

趁着大数量时代的到来,多少收集呢曾更换的越来越重要。前端埋点作为一个较成熟的多寡对接手段于广泛应用着。近期埋点分为两栽方法,有码与无码埋点。有码埋点相比较便于领悟,即调用SDK的API,在代码中插埋点的有关代码,实现用户作为采集。由于大家以出项目的下,埋点都是手动的,每趟业务需求的变动都设处处埋点,而无码埋点,即未待手动插入代码,只需要先前时期举办连锁安排,SDK自动收集用户作为,极大程度避免了坐要求变动、埋点错等由造成的重复埋点繁复工作。本文重要介绍无码埋点的技巧实现。

1.1 两种埋点的实现模式简介

埋点的不二法门分为三类:代码埋点、可视化埋点和无埋点。这里大概的牵线一下老两种植埋点格局:

(1)
代码埋点即凡于代码的关键部位植入所设收集数据的N行代码,需要开起产品本身,浓密摸底产品之事务逻辑与项目布局,下边代码模拟彰显的哪怕凡是点击提交订单的时光HubbleData
SDK代码埋点;

代码埋点示例

(2)
可视化埋点即用可视化交互的法子圈选出所设采访数据的控件,当用户作为有时,即可收集至相应的埋点数据。相比较于前方的代码埋点而言,可视化埋点可以解决代码埋点代价十分资本大之题目,然而力不从心活的自定义埋点属性。

可视化埋点流程

(3)
无埋点也于全埋点,即无待用户主动埋点,可以搜集用户拥有的操作行为,同样用可视化圈选,用户会将到所想征集的埋点数据,可以化解可视化圈选中数据不可回溯的问题。下图让闹了随便埋点多少收集的简流程。

无埋点数据收集流程

HubbleData
SDK的规划重点是代码埋点结合无埋点的数量收集形式,其中也论及到可视化埋点中的屏幕体系化及波绑定机制,本文首要介绍一下无埋点的计划和落实。

无码埋点的贯彻流程

1.2 无埋点SDK设计详细流程

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

不管埋点详细规划流程

自打上图能够见到,HubbleData的无埋点是于代码埋点的底蕴及实现的,所处任埋点的困难也就是集中在偏下三单方面:

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

正文重要就是立刻三单方面开展辨析,第二有些至关重要出口一下轩然大波唯一ID的规定,第三有紧要谈一下无埋点的募集的实现,重如若各样风波有采集的时和要采集的性能的布。

HubbleData
SDK还关乎到广大别样效能,包括屏幕连串可视化、代码埋点、精准渠道追踪等,这里不再介绍,前面会陆续分享有关的技能实现。

亿万先生 2

仲、事件唯一ID的规定

为了实现以可视化圈选的平时的风波之唯一性,每一个无埋点的风波采访都必须出还只来一个唯一的标识符来区分不同的事件。不同于代码埋点,用户可打定义之布局好所待的伊夫ntID,无埋点过程遭到,需要SDK自己安排各级一个征集事件的伊芙ntID,通过可视化圈选的操作,筛选出相应的伊夫(Eve)ntID所对应的数目音信。HubbleData采纳的是布局view唯一标识字符串的不二法门去唯一的标识这样的一个轩然大波,首要由view的层级结构path路径、该view的八方页面类名以及view所带的有自身定位属性等做,并透过SHA256编码来赢得唯一的伊夫(Eve)ntID。

下将整类别统介绍一些波唯一ID的变型过程。

1.但视化视图圈选,在页面及会晤冒出变化的圈子,拖动圆圈至思安排事件之控件上,将会合弹有输入事件之弹框。

2.1 控件的层级结构path构造

2.每当达到同样步的弹框中输入自定义之轩然大波名称,名称将相会及视图的viewPath绑定起来。viewPath是视图的绝无仅有标识,在下文中校详细讲解。

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的相继互换了,或者去了第一单,此时仍会赢得一些休精确之层级路径。此题材会合延续解决,会日益引入误差容量与相似度那些概念,即如若在误差范围外,则会进展进一步的配合,具体的化解方案本篇不以介绍。

3.用户点击了控件,判断控件是否绑定了事件,如绑定则举办事件上传。

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处于同一职务的选之埋点伊芙ntID不同,这里在构造唯一标志字符串的当儿还要在该UIAlertController的message和title音讯。3.5小节中谋面举行相关无埋点采集的介绍。

  • viewController的嵌套

貌似景色下,普通的view只需要依据一般的层系路径收集index即可,然则当有pageViewController时,如下图所展现分别被起了一个横向滚动(以店堂考拉app为条例)和纵向滚动(以集团严选app为例)的app的截图的示范:

事实上可以望,pageViewController会应用至繁app中,所以这好像app在动过程被的无埋点问题更是要考虑。

兑现流程中之技术点

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

一旦pageViewController中的逐一子页面不同,就算持续2.2节HubbleData会加盟页面controller的音讯来分别这一个不同之子页面,不过或许碰面由每个子页面插足的依次不同,导致每一次app进来的时段同一个页面的波会沾不同之伊芙(Eve)ntID,举例来表明一下,如达到图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值变了,层级路径不唯了,那么不论埋点采集的伊芙(Eve)ntID可能汇合由用户选用页面顺序的例外而各异,造成埋点数据的眼花缭乱。

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的子页面的景,不过会迎刃而解大部分之此类问题,对于有些其余非正规情况等,需详细分析页面布局举办分析。

从定义UIWindow的子类,当做悬浮小周,添加UIPanGestureRecognizer手势,按照手势的移动,设置悬浮框的运动。手势停止时取得悬浮窗主旨点的坐标。

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时,此时拿欠字段参加唯一标识字符串中即可区分。如今这块还免做相关处理,这里只是供一个简的解决思路。

遍历主window上之子视图,找到包含上述悬浮窗主旨点还会响应用户交互的无比里层视图,即为用户能够圈选的视图。

>三、无埋点的集的落实

参考iOS控件的音信传递链,有只着力措施。UIView hitTest:(CGPoint)point
with伊芙(Eve)nt:(UI伊夫nt
*)event。此API自动遍历子视图,找到包含point的视图,event传nil。由于event参数是nil,最终找到的视图并不一定是能响应用户手势的视图,尽管无可以响应则遍历其父视图,直到找到能响应用户作为的视图。

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的view威尔(Will)Appear方法,按照3.1给出的道:

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

当view威尔Appear函数执行时,插入埋点的代码。HubbleData的规划艺术为:

伊夫(Eve)ntID设置也固定的da_screen,即未会面透过伊夫(Eve)ntID来分各样页面的信,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等系统自带的一些。

最后谋面调用track伊夫(Eve)nt记录该采访的轩然大波,同上述介绍的代码埋点一样,调用的章程如下:

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

中properties即为上述要募的片段性。

视图唯一标识viewPath生成,上述手续皆以到了圈选的视图。怎么样确定视图的viewPath也是根本。viewPath需要全应用唯一,才得分别不同的事件。由于是无码,所以不得不由视图本身的性质去分析。我们可拿App的视图结构精晓成树的定义,树的彻底节点是UIWindow,树之条由UIViewController和UIView组成,叶子节点都是UIView。那么自从根节点交叶子节点的不二法门可以当做是唯一的。也不怕是视图的viewPath。下面介绍下实现的逻辑,viewPath由片组成部分组成,第一部分凡节点路径,另一样有些是和之对应之节点index。节点路径是由于每个节点的Class拼接而改为,节点index,就是节点在父节点吃的下标,比如子视图在父视图的subviews数组中之下标。下图是遍历节点的逻辑图。

3.3 UIControl之无埋点采集

对UIControl,HubbleData采纳的是hook
UIControl的sendAction:to:for伊芙(Eve)nt:方法。由法定文档可知,在UIControl执行相应之action时都相会首先调用sendAction:to:for伊芙(Eve)nt:方法,实现如下:

control

设想到UIControl的子类较多,所以HubbleData选用了内使用相比多的几乎栽举办了特种之解析:首假如UITextField、UIButton和UISwitch,另外的小未做特分析。具体的埋点的搜集计划呢:

不论哪类UIControl,伊芙ntID均以的凡第三组成部分介绍的绝无仅有标识字符串的SHA256虚构码值,可是相关采访properties有所出入。

亿万先生 3

3.3.1 UITextField

UITextField是UIControl的一个子类,由于UIText菲尔德(Field)涉及到用户之心曲比较多,比如用户称、密码、聊天文本等,所以HubbleData不会面对此类的UIText菲尔德(Field)(Field)举办埋点的采集。

HubbleData重要收集的是UISearchBar中之UIText菲尔德(Field)(Field),即UISearchBarTextField,并收获搜索的文本内容,这对有些电商类的App来说,可以相比较好的分析用户感兴趣之货色等,这是用作HubbleData
SDK无埋点的一个需要。

hook住sendAction:to:forEvent:后,如果对UISearchBarTextField的所有actions都进行hook的话,那么_searchFieldBeginEditing、_search菲尔德(Field)EndEditing等具备的action暴发的下还相会展开数据的集,会采集到多无效的音信,导致采集的数错乱。HubbleData
SDK只有当_searchFieldEndEditing
action暴发时才会师进展埋点,收集之properties为:

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

那般虽可知针对搜索框举行无埋点采集,并会收集搜索的文书内容。此道才是当_searchField(Field)EndEditing发生常募集数据,有或该action执行时未尝尽兴真正的寻找操作,可能会师暨工作数据库的数量发生出入,可是也能较规范之辨析用户感兴趣的搜寻内容。

测算节点的index,这个手续,有种特殊的视图需要注意,可复用视图的index是和数据源相关的,比如UITableViewCell,此类视图的index不可知拔取父视图的subviews的下标代替,应该用数据源的下标代表,比如cell的indexPath.section:indexPath.row。下边被来一个简便视图和而复用视图的viewPath的例证。TestViewController-UIView-UIButton&0-0-0同TableViewController-UITableView-UITableViewCell&0-0-1:0。

3.3.2 UIButton

UIControl中以最多尽广的凡UIButton,由此对UIButton的集很关键。在应用UIButton的时候可以肆意的安装其title等属性来代表事情逻辑的例外状态。这里可以选一个概括的例子:基本app的记名页面,在用户称和密码都不输入时、都输入时和登录中逐一状态,登录按钮的title、titleColor等性能可能都是差之,即各级一样种植button的体裁都意味正同种样式,可是得的伊夫ntID是相同的。针对此种情状,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不同,所以得到的每个按钮的风波的唯一伊芙ntID都是差的,这样晚端平在解析的早晚,无法归类同类元素。当HubbleData给出frame时,后端可以遵照frame归类出同一好像按钮的波,具体的分类策略这里不再介绍。

何以检测用户触发了绑定了风波ID的视图也是根本,此处运用的大旨技术是runtime中Method
Swizzle。下边介绍一下对准不同品类的控件,如何hook相应的法门。

3.3.3 UISwitch

恍如于UIButton,只然则这里而集switchState,即眼前底开关状态,具体的征集属性也:

(1) type 为UIControl采集的事件类型,这里设置为switchEvent;
(2) page 为当前页面的名称,用于前端显示用;
(3) switchState 为switch的开关状态;
  1. UIControl类型的控件hook – (void)sendAction:(SEL) to:(id)target
    for伊芙nt:(UI伊夫(Eve)nt *)event

  2. UIScrollView,UITextView,UITableView,UICollectionView
    类型的控件,先hook -(void)setDelegate:(id)delegate
    方法,然后再度hook想使采访事件之代理方,例如 textViewDidBeginEditing
    、tableview:(UITableView *)tableview
    didSelectRowAtIndexPath:(NSIndexPath *)indexPath 等。

  3. 拉出手势事件之视图 hook
    -(void)addGestureRecognizer方法,并在章程实现中被手势对象上加新的target和action
    ,- (void)addTarget:(id)target action:(SEL)action。

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

伊芙(Eve)ntID依照上述介绍的措施赢得,只但是这里要注意的凡,获取的并无是UITableView的绝无仅有标识字符串而是对应的点击的cell的唯一标识字符串。采集的properties为:

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

无码埋点的关键技术,就是以上分析的几乎碰,首先通过可视化圈选得到要绑定事件视图,并转移唯一标识viewPath,通过hook系统控件的方,得到用户触发的视图,生成视图的viewPath与地面的事件列表比对,比对成则达传viewPath对应之风波。

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的唯一标识标识字符串编码作为伊夫(Eve)ntID,采集的特性为:

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

UIAlertController的出格处理

此间要针对UIAlertController做一个详尽的验证,因为UIAlertController在点击诸如撤消、确定的选料项按钮时,也相会举办手势的埋点采集,不过当iOS9和iOS10达到稍稍有若干区别。

此地先盖iOS9为条例,其target是企图在_UIAlertControllerView这么些类其余私有类上的,假诺直接针对那_UIAlertControllerView举行唯一标识字符串的构造,则废除同规定选项得到的伊夫ntID是同样之,这样以无法精确的分析有用户的选项,所以要以每个选项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(退群)

正文原创首发于Cobub官网博客,作者xd
Xu.

四、总结

章重要介绍了HubbleData无埋点SDk在iOS端的设计和贯彻,涉及的第一内容:事件唯一ID的确定和一些无埋点的贯彻,当然在无埋点SDK的计划出中尚撞了各式各类的问题。鉴于小说的篇幅都相比较充足,一些题材的化解与关键技术的贯彻,比如精准渠道追踪、hook争持解决、代码埋点的实现、屏幕体系化以及可视化圈选部分的内容,本篇著作不再介绍,将晤面于继续文章被延续介绍。

如需转载请讲明出处!

Cobub社区QQ194022996

相关文章