科技美学知乎HubbleData无埋点SDK在iOS端的设计与实现

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.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不同,所以得到的每个按钮的轩然大波的唯一伊夫(Eve)ntID都是例外的,这样后端在分析的时候,不能归类同类元素。当HubbleData给出frame时,后端可以按照frame归类出同一类按钮的轩然大波,具体的分类策略这里不再介绍。

3.3.4 其余UIControl

此外的只是采集type,page属性,近期未做过多的处理。

3.3.3 UISwitch

好像于UIButton,只不过这里要搜集switchState,即眼前的开关状态,具体的采访属性为:

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

3.3 UIControl的无埋点采集

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

control

设想到UIControl的子类较多,所以HubbleData采取了内部使用较多的二种举办了特其它分析:首倘若UITextField、UIButton和UISwitch,另外的暂时未做特殊分析。具体的埋点的搜集计划为:

随便哪一类UIControl,伊芙ntID均接纳的是第三部分介绍的唯一标识字符串的SHA256编码值,不过相关采访properties有所出入。

(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的类名获取其不同的唯一标识字符串。

1.2 无埋点SDK设计详细流程

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

无埋点详细规划流程

从上图可以观察,HubbleData的无埋点是在代码埋点的基础上实现的,所处无埋点的难点也就集中在以下两个方面:

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

正文重要就这六个方面展开剖析,第二有些至关重要讲一下轩然大波唯一ID的确定,第三局部首要讲一下无埋点的募集的实现,首即使各个风波时有暴发采集的火候以及待采集的性质的部署。

HubbleData
SDK还论及到众多另外职能,包括屏幕系列可视化、代码埋点、精准渠道追踪等,这里不再介绍,前面会陆续分享相关的技术实现。

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;
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在使用过程中的无埋点问题尤为要考虑。

3.2 UIViewController的无埋点采集

最紧假使采访页面的生命周期,这里HubbleData采取的是hook
UIViewController的view威尔(Will)Appear方法,按照3.1提交的措施:

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

当view威尔(Will)Appear函数执行时,插入埋点的代码。HubbleData的统筹方法为:

伊芙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伊夫nt记录该征集的风波,同上述介绍的代码埋点一样,调用的章程如下:

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

内部properties即为上述要搜集的部分性质。

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的唯一标识标识字符串编码作为伊芙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(退群)
(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.1 控件的层级结构path构造

四、总结

作品首要介绍了HubbleData无埋点SDk在iOS端的设计与落实,涉及的关键内容:事件唯一ID的规定和部分无埋点的落实,当然在无埋点SDK的计划性开发中还碰着了多种多样的问题。鉴于著作的篇幅已经较长,一些题材的化解以及关键技术的贯彻,比如精准渠道追踪、hook争执解决、代码埋点的落实、屏幕系列化以及可视化圈选部分的内容,本篇著作不再介绍,将会在持续著作中连续介绍。

3.1 AOP 简介

上边讲一下无埋点的现实性贯彻,用到的机假诺AOP(Aspect-Oriented-Programming),面向切面编程,面对的是处理过程中的某个步骤和章程。在运转时,动态的将代码插入到类的制定办法、指定地点上的编程思想就是面向切面编程。熟悉iOS
Runtime的应有很通晓,相关的介绍小说也很多,这里不再过多的废话。

HubbleData无埋点的兑现重点就是借助AOP,hook对应类的办法,并在原实现代码的根基上插入自己定义的埋点的代码,当该类的被hook的函数执行时,就能实现无埋点数据搜集的功用。下面给出HubbleData里面Method
Swizzling的一个简短的贯彻。

Method Swizzling

上述代码只是给出了一个简便的兑现的逻辑结构,new_swizzledMethod也只是selector没有参数的情事(除去self和_cmd),真正在埋点的处理过程需要考虑的状态比较多。

二、事件唯一ID的确定

为了落实在可视化圈选的时的轩然大波的唯一性,每一个无埋点的事件采访都必须有且仅有一个唯一的标识符来区分不同的轩然大波。不同于代码埋点,用户可以自定义的部署自己所需的伊夫(Eve)ntID,无埋点过程中,需要SDK自己配置每一个收集事件的伊夫(Eve)ntID,通过可视化圈选的操作,筛选出相应的伊夫(Eve)ntID所对应的数量消息。HubbleData接纳的是社团view唯一标识字符串的艺术去唯一的标识这样的一个轩然大波,紧要由view的层级结构path路径、该view的到处页面类名以及view所带的有些自我定位属性等整合,并经过SHA256编码来博取唯一的伊芙ntID。

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

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的各种交换了,或者去除了首个,此时如故会取得部分不规范的层级路径。此问题会连续解决,会逐步引入误差容量和相似度这一个定义,即只要在误差范围内,则会举办更加的配合,具体的化解方案本篇不在介绍。

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

1.1 两种埋点的贯彻模式简介

埋点的形式分为三类:代码埋点、可视化埋点和无埋点。这里大概的介绍一下两种埋点情势:

(1)
代码埋点即是在代码的关键部位植入所要收集数据的N行代码,需要挖开产品我,深切了然产品的事情逻辑及项目协会,下边代码模拟展现的即是点击提交订单的时候HubbleData
SDK代码埋点;

代码埋点示例

(2)
可视化埋点即用可视化交互的章程圈选出所要采集数据的控件,当用户作为时有爆发时,即可收集到相应的埋点数据。相比于前方的代码埋点而言,可视化埋点能够化解代码埋点代价大成本高的问题,不过力不从心灵活的自定义埋点属性。

可视化埋点流程

(3)
无埋点也叫全埋点,即不需要用户积极埋点,能够收集用户所有的操作行为,同样应用可视化圈选,用户可以拿到所想采集的埋点数据,可以解决可视化圈选中数量不可回溯的题目。下图给出了无埋点多少收集的粗略流程。

无埋点数据搜集流程

HubbleData
SDK的计划性重点是代码埋点结合无埋点的数量收集格局,其中也提到到可视化埋点中的屏幕体系化及事件绑定机制,本文首要介绍一下无埋点的统筹与贯彻。

0 引言

多年来在承担集团的HubbleData的埋点SDK的开销任务,产品的雏形其实在几年前就已经有了,企业内部的比如考拉、易信、LOFTER、美学、漫画等多款产品都已连接使用。

下图给出HubbleData SDK某个应用的有些分析的显得页面:

(1)概览示意图

事件

(2)事件分析示意图

事件

(3)实时分析示意图

事件

除此以外HubbleData平台还具有留存分析、漏斗分析、粘性分析、数据看板等多种功力,方便有关负责人士对产品用户作为展开更进一步的追究分析。

老版本的SDK的计划性是代码埋点实现的,尽管对于一些比较成熟的产品,代码埋点完全可以达到产品方的要求,不过对于有些新开行或者需频繁转移的急需的新产品等,考虑到其怜惜的本钱大,代价高等缺点,HubbleData无埋点SDK的宏图就显得更为重大了。

自身根本负责iOS端无埋点以及可视化圈选的工作,作品紧要系统讲授一下HubbleData无埋点SDK在iOS端的设计与贯彻和一些息息相关题材的缓解,后续将本着所有埋点的兑现流程与可视化圈选等情节再作分享。

一、埋点简介

3.3.1 UITextField

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

HubbleData重要收集的是UISearchBar中的UITextField(Field),即UISearchBarTextField(Field),并获取搜索的文书内容,这对于有些电商类的App来说,可以较好的剖析用户感兴趣的货品等,这是用作HubbleData
SDK无埋点的一个需要。

hook住sendAction:to:forEvent:后,如果对UISearchBarTextField的所有actions都进行hook的话,那么_searchFieldBeginEditing、_searchField(Field)EndEditing等有着的action发生的时候都会展开多少的募集,会收集到很多没用的新闻,导致采集的多寡错乱。HubbleData
SDK唯有当_searchFieldEndEditing
action暴发时才会举办埋点,收集的properties为:

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

诸如此类就能对搜索框举办无埋点采集,并能收集搜索的公文内容。此形式只是在_search菲尔德(Field)EndEditing暴发时采访数据,有可能该action执行风尚未尽兴真正的追寻操作,可能会与工作数据库的数码有出入,可是也可以相比较规范的辨析用户感兴趣的查找内容。