iOS自動(dòng)化埋點(diǎn)探索

https://mp.weixin.qq.com/s/u-HmmrSAgtER1N2pKxCm0A

隨著公司業(yè)務(wù)的發(fā)展质况,數(shù)據(jù)的重要性越來越突出敌买。大中型公司甚至一些小型互聯(lián)網(wǎng)公司,都建立了自己的數(shù)據(jù)采集筋帖、上報(bào)和分析平臺(tái)。而數(shù)據(jù)的采集是整個(gè)流程非常重要的一個(gè)環(huán)節(jié),只有保證數(shù)據(jù)的采集的全面和精準(zhǔn)坐搔,后面的分析才有意義。為了解決數(shù)據(jù)的正確性敬矩、維護(hù)難度和開發(fā)效率問題上概行,很多公司都提出了自己的技術(shù)方案。這些埋點(diǎn)方案大體可以分為三類:

代碼埋點(diǎn)

由開發(fā)人員在觸發(fā)事件的具體方法里弧岳,植入多行代碼把需要的數(shù)據(jù)存下來凳忙,然后根據(jù)上報(bào)策略把前一個(gè)時(shí)間段收集的數(shù)據(jù)上傳到后臺(tái)。

可視化埋點(diǎn)

通過可視化工具圈選具體頁面元素并生成配置禽炬,在用戶操作時(shí)涧卵,自動(dòng)根據(jù)配置判斷是否需要采集該事件。

無埋點(diǎn)

無埋點(diǎn)并不是不需要埋點(diǎn)腹尖,而是在應(yīng)用頁面的加載柳恐、點(diǎn)擊等事件前自動(dòng)嵌入監(jiān)測(cè)代碼來采集數(shù)據(jù),它會(huì)采集所有感興趣的事件類型的埋點(diǎn)热幔。其實(shí)我們更愿意稱它為全埋點(diǎn)乐设。

京東客戶端現(xiàn)在主要使用第一種方案,即代碼埋點(diǎn)绎巨。這種方案的好處是近尚,用起來比較簡單,在收集個(gè)性化數(shù)據(jù)時(shí)也比較靈活场勤。但是也有一些問題戈锻,比如:

**+ **新增埋點(diǎn)依賴App發(fā)版,影響數(shù)據(jù)收集時(shí)機(jī)和媳。

**+ **App發(fā)版需要埋點(diǎn)工作完成格遭,影響版本進(jìn)度。

**+ **埋點(diǎn)代碼和業(yè)務(wù)代碼耦合在一起窗价,增加代碼維護(hù)難度如庭。

**+ **如果埋點(diǎn)錯(cuò)誤只能更新版本解決(Apple在2017年初全面禁止使用HotFix來修復(fù)bug)。

為了解決這些問題撼港,我們調(diào)研了市面上的方案坪它,在調(diào)研過程中,我們發(fā)現(xiàn)很多公司都看到了這些問題帝牡,他們也提出了自己的解決方案往毡,基本上都是圍繞可視化埋點(diǎn)方案來做的。這種方案好處是靶溜,埋點(diǎn)提報(bào)方式和數(shù)據(jù)后臺(tái)基本不需要修改开瞭,風(fēng)險(xiǎn)也比較可控懒震。而無埋點(diǎn)方案由于全部數(shù)據(jù)都收集,造成數(shù)據(jù)量巨大嗤详,這給服務(wù)器和網(wǎng)絡(luò)傳輸帶來較大負(fù)載个扰,另外數(shù)據(jù)清洗難度也非常大,基于這些原因葱色,大部分公司都沒有選擇這種方案递宅。基于這些這些原因和結(jié)合我們的場(chǎng)景后苍狰,我們選擇了可視化埋點(diǎn)方案來解決代碼埋點(diǎn)的問題办龄。

image

可視化埋點(diǎn)并不是擯棄了代碼埋點(diǎn),而是在代碼埋點(diǎn)的上層封裝的一套邏輯來代替手工埋點(diǎn)淋昭,大體上架構(gòu)如下圖:

image.gif

不過要實(shí)現(xiàn)可視化埋點(diǎn)也有很多問題需要解決俐填,比如如何確定頁面元素的唯一標(biāo)識(shí)、如何攜帶業(yè)務(wù)參數(shù)翔忽、如何添加有判斷邏輯的埋點(diǎn)和配置信息的版本管理英融。下面我們會(huì)整體介紹可視化埋點(diǎn)的使用方式和技術(shù)細(xì)節(jié),另外針對(duì)上面的問題我們會(huì)嘗試給出解決方案和一些思考呀打。

整體概覽

整體概覽的介紹分為2個(gè)部分:產(chǎn)品原型概覽和技術(shù)原理概覽矢赁。首先介紹產(chǎn)品原型概覽,可以更直觀了解可視化埋點(diǎn)的基本運(yùn)作流程贬丛。

產(chǎn)品原型概覽

首先在App中嵌入可視化埋點(diǎn)SDK撩银。當(dāng)開啟圈選開關(guān)之后,會(huì)在屏幕上始終懸浮一個(gè)圈選開關(guān)豺憔,用于埋點(diǎn)維護(hù)人員采集埋點(diǎn)配置信息额获。如下圖所示:

image.gif

圈選開關(guān)的按鈕一共有3個(gè),當(dāng)選擇圈選按鈕的時(shí)候恭应,點(diǎn)擊頁面上的元素抄邀,SDK會(huì)攔截點(diǎn)擊事件,彈出一個(gè)用于收集配置信息的視圖昼榛。檢測(cè)按鈕用于版本管理境肾,下文再詳細(xì)介紹。關(guān)閉按鈕用于關(guān)閉圈選功能胆屿,可以正常的操作App頁面元素奥喻。

開啟圈選開關(guān),選擇頁面元素進(jìn)行埋點(diǎn)配置采集非迹。例如环鲤,點(diǎn)擊上圖所示頁面右下方的加入購物車按鈕,彈出配置視圖憎兽,如下圖所示:

image.gif

視圖會(huì)展示一些信息冷离,其中最重要的是SDK生成的唯一標(biāo)識(shí)符吵冒,用于對(duì)埋點(diǎn)進(jìn)行標(biāo)識(shí)。埋點(diǎn)維護(hù)人員需要填寫eventId西剥,選擇一些要上報(bào)的數(shù)據(jù)字段等操作痹栖。上圖左上角的增加按鈕,用于一個(gè)點(diǎn)擊事件有多個(gè)埋點(diǎn)的需求蔫耽,點(diǎn)擊增加结耀,會(huì)在下方新增一個(gè)信息采集視圖留夜,以供埋點(diǎn)采集匙铡。上報(bào)類型是跟我們具體業(yè)務(wù)相關(guān)的,可以忽略碍粥。頁面參數(shù)鳖眼、事件參數(shù)的選擇,會(huì)在下文說明攜帶上報(bào)數(shù)據(jù)部分的思路介紹嚼摩∏栈洌總之,采集完畢會(huì)形成一條配置信息枕面,上傳到服務(wù)器愿卒。采集完成全部的配置信息,形成一個(gè)埋點(diǎn)配置列表潮秘。

在用戶啟動(dòng)App時(shí)琼开,埋點(diǎn)配置列表會(huì)被下載下來。當(dāng)用戶點(diǎn)擊加入購物車按鈕時(shí)枕荞,SDK會(huì)使用和上文中配置采集階段相同的方法柜候,生成唯一標(biāo)識(shí)符,用于在埋點(diǎn)配置列表查找相關(guān)配置項(xiàng)躏精,如果匹配成功渣刷,則利用這些配置數(shù)據(jù),自動(dòng)的進(jìn)行埋點(diǎn)上報(bào)矗烛。

整體的產(chǎn)品原型概覽先介紹到這辅柴,下面看一下技術(shù)原理概覽。

技術(shù)原理概覽

采用AOP(Aspect-Oriented-Programming)即面向切面編程的思想瞭吃,基于 Runtime 的 Method Swizzling能力碌嘀,來 hook 相應(yīng)的方法,從而在hook方法中進(jìn)行統(tǒng)一的埋點(diǎn)處理虱而。例如所有的按鈕被點(diǎn)擊時(shí)筏餐,都會(huì)觸發(fā)UIApplication的sendAction方法,我們hook這個(gè)方法牡拇,即可攔截所有按鈕的點(diǎn)擊事件魁瞪。

這里的處理分為2個(gè)部分:采集埋點(diǎn)配置信息穆律,和真實(shí)的埋點(diǎn)數(shù)據(jù)上報(bào)。這個(gè)和上文產(chǎn)品原型概覽部分介紹的處理流程相對(duì)應(yīng)导俘。

以按鈕點(diǎn)擊事件的處理為例峦耘,大致的流程如下圖所示:

image.gif

這里僅僅是以按鈕為例說明,UITableView旅薄、UICollectionView辅髓、UIView的手勢(shì)等等,都是同樣的處理邏輯少梁,對(duì)可視化埋點(diǎn)有過研究的人應(yīng)該都了解這個(gè)過程洛口,這里不再過多闡述。下面來詳細(xì)的探討SDK的關(guān)鍵模塊的技術(shù)實(shí)現(xiàn)思路凯沪。

關(guān)鍵模塊實(shí)現(xiàn)思路

我們要討論的SDK的關(guān)鍵模塊分為3個(gè)部分:生成唯一標(biāo)識(shí)符第焰、埋點(diǎn)數(shù)據(jù)攜帶、版本管理妨马。其余部分挺举,例如hook的具體實(shí)現(xiàn)、數(shù)據(jù)的上傳烘跺、下載匹配湘纵、圈選工具的交互等,雖然也都是需要解決一些技術(shù)問題滤淳,但是都有比較清晰的實(shí)現(xiàn)方案梧喷,這些方面不作討論。下面來看第一個(gè)問題娇钱。

唯一標(biāo)識(shí)符

市面上可視化埋點(diǎn)方案伤柄,大多都使用viewPath生成唯一標(biāo)識(shí)符。我們知道App的視圖層次是一個(gè)樹狀結(jié)構(gòu)文搂。一個(gè) view可以被認(rèn)為是一個(gè)節(jié)點(diǎn)适刀,處于視圖樹的某一個(gè)位置,從根節(jié)點(diǎn)到這個(gè)view節(jié)點(diǎn)的深度信息構(gòu)成了一個(gè)path煤蹭,用來唯一標(biāo)識(shí)該view笔喉。

如下圖所示,

**^ **view1的viewPath形如:0-0硝皂,

^ view2的viewPath形如:0-1,

^ view3的viewPath形如:0-1-0,

**^ **view4的viewPath形如:0-1-1常挚。

image.gif

這種方式有諸如可讀性、數(shù)據(jù)計(jì)算量稽物、系統(tǒng)視圖干擾等一系列的麻煩要處理奄毡。除此之外,最關(guān)鍵的問題是這種方式僅僅適用于靜態(tài)視圖贝或。還是拿上圖舉例吼过,假如某一時(shí)刻锐秦,view1被移除,那么view2的viewPath變成了0-0,它的子視圖的viewPath也相應(yīng)發(fā)生變化盗忱,這種情況下酱床,viewPath無法用來唯一標(biāo)識(shí)某個(gè)視圖,唯一標(biāo)識(shí)符就不再唯一了趟佃。盡管也有相應(yīng)的優(yōu)化措施扇谣,例如在viewPath中引入className,但是這種方式只是很輕微的緩解了問題闲昭。在強(qiáng)調(diào)頁面配置化的場(chǎng)景罐寨,整個(gè)頁面的元素的位置、順序汤纸、是否展示衩茸,幾乎都要依靠服務(wù)端下發(fā),引入className的優(yōu)化恐怕并沒有明顯效果贮泞,而且增加了復(fù)雜度。所以這種方案還需要很大程度的提升和優(yōu)化才行幔烛。

位置信息是可變的啃擦,所以viewPath這種方式是從可變的要素來生成唯一標(biāo)識(shí)符,我們并沒有在研究viewPath上花費(fèi)太多時(shí)間饿悬,而是換一種角度思考令蛉,引入相對(duì)不變的要素來生成唯一標(biāo)識(shí)符:target+action。

獲取target+action的方式非常簡單高效狡恬,可以直接獲取一個(gè)UIButton的target和action珠叔,UIView可以通過UIRecognizeGesture獲取target和action、UITableview的delegate和didSelectedRowAtIndexPath等等弟劲〉话玻可以發(fā)現(xiàn),無論一個(gè)view顯示在任何位置兔乞,它的target和action都不會(huì)變化(除非某一個(gè)特殊情況下汇鞭,功能發(fā)生變化,target和action才會(huì)變庸追,不過顯然這個(gè)時(shí)候原始的埋點(diǎn)應(yīng)該也及時(shí)廢棄或者添加新的埋點(diǎn))霍骄。這樣去除了可變要素,利用不可變要素來生成唯一標(biāo)識(shí)符淡溯,相對(duì)來說會(huì)更加可靠读整。

但是現(xiàn)實(shí)場(chǎng)景下,并不會(huì)總是一個(gè)按鈕對(duì)應(yīng)著一個(gè)單一邏輯咱娶,在某種條件下進(jìn)行區(qū)分埋點(diǎn)非常常見米间,例如在一個(gè)按鈕的處理事件中煎楣,可能會(huì)需要在condition1的情況下,需要執(zhí)行A邏輯车伞,然后埋A點(diǎn)择懂,在condition2的情況下,執(zhí)行B邏輯另玖,埋B點(diǎn)困曙。這時(shí),無論使用viewPath還是target+action谦去,都不能解決唯一標(biāo)識(shí)問題慷丽。特別是condition多種多樣,增加了問題的復(fù)雜度鳄哭,比如有些地方使用某一個(gè)對(duì)象的屬性或者服務(wù)端下發(fā)的字段作為條件判斷要糊,有些地方使用視圖的狀態(tài)等信息作為條件判斷。從這里我們也能發(fā)現(xiàn)代碼埋點(diǎn)的優(yōu)勢(shì)妆丘,你可以利用一切編程的靈活和便利性來達(dá)到目的锄俄,這恰恰成為了可視化埋點(diǎn)要面臨的困難。而使用target+action的方式還有一個(gè)麻煩需要處理勺拣,比如2個(gè)view的target+action是一樣的奶赠,但是要求不一樣的埋點(diǎn)。這兩種情況增加了生成唯一標(biāo)識(shí)符的困難药有。本質(zhì)上這兩種情況可以歸并為一種毅戈,多條件埋點(diǎn)或者有條件埋點(diǎn)。

我們的方案是增加一個(gè)protocol如下:

image.gif

舉個(gè)例子:假如有一個(gè)按鈕愤惰,在condition1的情況下要執(zhí)行doSom1這件事情苇经,在condition2的情況下要執(zhí)行doSom2這件事情

那么開發(fā)者要讓target在實(shí)現(xiàn)點(diǎn)擊事件的同時(shí),還要實(shí)現(xiàn)上面的協(xié)議方法宦言。

image.gif

SDK會(huì)自動(dòng)調(diào)用這個(gè)方法扇单,把返回的標(biāo)識(shí)追加到target+action的后面。protocol這種做法雖然解決了唯一標(biāo)識(shí)問題蜡励,但是其實(shí)是把問題的復(fù)雜度拋出去令花,把區(qū)分condition的工作交給了開發(fā)者。所以這種方式也只是折衷的處理方案凉倚。

總是有一些方案兼都,使用覆蓋率來衡量可視化埋點(diǎn)方案的適用情況。就是說稽寒,使用可視化埋點(diǎn)扮碧,可以替換百分之多少的代碼埋點(diǎn)。但是有條件埋點(diǎn)問題不解決的話,這個(gè)覆蓋率是沒有意義的慎王。因?yàn)樵诼顸c(diǎn)采集(圈選)階段蚓土,采集者可能壓根不知道這個(gè)按鈕是單一埋點(diǎn)還是帶條件的,如果采集錯(cuò)誤的話赖淤,上報(bào)的埋點(diǎn)數(shù)據(jù)就會(huì)不準(zhǔn)確蜀漆。也有些人推薦多種組合的埋點(diǎn)方式,即代碼埋點(diǎn)咱旱、可視化埋點(diǎn)确丢、無埋點(diǎn)等組合使用,這看起來是個(gè)很不錯(cuò)的想法吐限,不過在此之前鲜侥,我們首先要解決明確邊界問題,讓多種方式協(xié)同工作诸典。

埋點(diǎn)數(shù)據(jù)攜帶

一個(gè)具體的埋點(diǎn)上報(bào)內(nèi)容描函,可能還要求攜帶一些頁面或者業(yè)務(wù)數(shù)據(jù)。埋點(diǎn)攜帶數(shù)據(jù)的問題狐粱,其實(shí)并不僅僅是可視化埋點(diǎn)需要面對(duì)舀寓,這是一個(gè)普遍的問題,跟埋點(diǎn)方式無關(guān)脑奠。還有前端埋點(diǎn)基公、后端埋點(diǎn)之爭,如果采取后端埋點(diǎn)宋欺,有些數(shù)據(jù)可能只能從前端獲取到。大家都覺得代碼埋點(diǎn)帶來代碼耦合胰伍,而且也比較繁瑣齿诞,但是采取無埋點(diǎn)的話,如何解決巨大的數(shù)據(jù)流量和后端數(shù)據(jù)清洗的問題骂租〉昏荆總之,自動(dòng)化埋點(diǎn)的技術(shù)探索還處于蠻荒階段渗饮,各家自成一體但汞,沒有一個(gè)成熟的解決方案。

由于這么多的問題難以解決互站,現(xiàn)在市面上主要還是依賴代碼埋點(diǎn)的方式私蕾。代碼埋點(diǎn)繁瑣,需要跟業(yè)務(wù)邏輯緊緊耦合在一起胡桃;但是這種方式特別靈活踩叭,在應(yīng)用開發(fā)中,一個(gè)復(fù)雜頁面可能包含許多模塊、視圖容贝、業(yè)務(wù)處理類等自脯,數(shù)據(jù)也可能從多個(gè)接口下發(fā),分布在這些零散的地方斤富。代碼埋點(diǎn)跟隨業(yè)務(wù)邏輯各自分布在這些零散模塊中膏潮,所以可以精準(zhǔn)的獲取這些模塊中的數(shù)據(jù),這就成為了代碼埋點(diǎn)的優(yōu)勢(shì)满力。我們提出可視化埋點(diǎn)的解決方案焕参,其實(shí)還是站在代碼埋點(diǎn)的視角看待問題,希望能用統(tǒng)一的方式解決代碼埋點(diǎn)的繁瑣脚囊、耦合問題龟糕,又不能犧牲代碼埋點(diǎn)的優(yōu)勢(shì)和功能。

許多的可視化埋點(diǎn)方案悔耘,都是把埋點(diǎn)數(shù)據(jù)攜帶環(huán)節(jié)一筆帶過讲岁。僅僅指出用KVC等方式進(jìn)行取值上報(bào),并沒有實(shí)際的技術(shù)方案衬以。其實(shí)這里存在非常多的疑點(diǎn)缓艳。譬如,數(shù)據(jù)存在什么地方看峻?綁定在view上阶淘,還是在controller上,數(shù)據(jù)需要集中堆放到某個(gè)地方么互妓。最基本的數(shù)據(jù)有服務(wù)端下發(fā)的字段和object本身的屬性溪窒,key是怎么規(guī)定的?KVC的方式是運(yùn)行時(shí)特性冯勉,如果字段疏忽大意寫錯(cuò)了澈蚌,或者發(fā)生了變化但是key沒有及時(shí)更新,KVC的方式如何給出提示灼狰?

KVC要處理和面對(duì)如此多的問題宛瞄,所以我們認(rèn)為這種方式來存取數(shù)據(jù)并不合適。在上面交胚,我們也引出了埋點(diǎn)數(shù)據(jù)上報(bào)方案的各種問題份汗,總之由于各種各樣技術(shù)和現(xiàn)實(shí)問題的制約,各個(gè)公司可能都發(fā)展了自己的一套埋點(diǎn)方案蝴簇,經(jīng)過了很長時(shí)間的發(fā)展杯活,各端都趨于穩(wěn)定。如果修改數(shù)據(jù)上報(bào)方案军熏,還要兼顧考慮各端需要改造的成本和風(fēng)險(xiǎn)轩猩,在徹底解決這些問題之前,我們提出的方案還是要基于當(dāng)前的數(shù)據(jù)上報(bào)方案。

既然是基于我們當(dāng)前的數(shù)據(jù)上報(bào)方案均践,還是先看看攜帶的埋點(diǎn)數(shù)據(jù)的一些特征:埋點(diǎn)攜帶的業(yè)務(wù)相關(guān)的數(shù)據(jù)主要分為3類:頁面參數(shù)晤锹、事件參數(shù)、擴(kuò)展參數(shù)彤委。頁面參數(shù)鞭铆,顧名思義是跟頁面相關(guān)的數(shù)據(jù),一般情況下焦影,一個(gè)頁面下的所有埋點(diǎn)车遂,頁面參數(shù)應(yīng)該都是一致的,或者說就固定的幾種類型斯辰。事件參數(shù)類型非常多舶担,一般都是跟具體的點(diǎn)擊事件的業(yè)務(wù)相關(guān)。而擴(kuò)展參數(shù)彬呻,我們這邊是作為一個(gè)補(bǔ)充衣陶,用來上報(bào)一些額外的參數(shù),例如商品詳情頁面闸氮,擴(kuò)展參數(shù)可能會(huì)有店鋪id剪况,商品的分類等等信息,一般也都是幾種固定的類型蒲跨。

上報(bào)的這些數(shù)據(jù)译断,并不都是服務(wù)端下發(fā)什么,然后原樣傳回去或悲,而是會(huì)經(jīng)過客戶端的一系列處理孙咪。比如可能會(huì)寫一大堆邏輯,if某種業(yè)務(wù)巡语,采集字段A该贾,else某種業(yè)務(wù),采集字段B捌臊;而且也不僅僅是條件判斷领虹,許多的字段會(huì)抽象成0毅否、1這樣的數(shù)字來表示寝殴,比如并不會(huì)直接使用字段A菌瘫,而是用0來替代病瞳,B用1來替代等等您觉,最后許多個(gè)這樣的字段會(huì)使用下劃線拼接起來楣号,形如:0_1_1_0_1_0_0_0_1刽脖。這些數(shù)據(jù)上報(bào)到后臺(tái)举庶,如果需要提數(shù)执隧,會(huì)有專門的程序來解析這些數(shù)字拼接的字符串。

前面我們說過,不會(huì)改變數(shù)據(jù)上報(bào)方案镀琉,上面介紹的方式改造成本很高峦嗤,我們還是用上述的方式來處理數(shù)據(jù)。但是需要提供一個(gè)統(tǒng)一的入口屋摔,以便于可視化埋點(diǎn)SDK可以訪問烁设。這里,我們提供一個(gè)protocol钓试,可以讓target或者是controller實(shí)現(xiàn)協(xié)議装黑,這個(gè)方法返回一個(gè)字典,把之前處理數(shù)據(jù)的邏輯遷移到這里作為value弓熏,key用來標(biāo)識(shí)數(shù)據(jù)恋谭。protocol如下所示:

image.gif

target或者是controller實(shí)現(xiàn)協(xié)議,如下所示:

image.gif

這種方式還便于采集配置挽鞠,在圈選的時(shí)候疚颊,SDK會(huì)自動(dòng)調(diào)用target和controller的這個(gè)方法,并且把所有的key值顯示出來滞谢,采集字段的時(shí)候串稀,直接選擇某一個(gè)key即可,如下圖所示:

image.gif

當(dāng)選擇某一個(gè)key的時(shí)候狮杨,會(huì)同時(shí)增加一個(gè)source字段母截,記錄下這個(gè)key是來自于target還是controller。這些信息都作為配置信息被采集橄教。當(dāng)用戶在使用App清寇,進(jìn)行真實(shí)的埋點(diǎn)上報(bào)的時(shí)候,會(huì)根據(jù)source決定調(diào)用target還是controller的方法护蝶,同樣返回的字典华烟,使用key來獲取對(duì)應(yīng)的數(shù)據(jù)即可。

版本管理

生成控件的唯一標(biāo)識(shí)符是可視化埋點(diǎn)的一個(gè)重要環(huán)節(jié)持灰,無論是viewPath也好盔夜,還是target+action的方式,標(biāo)識(shí)符都會(huì)包含一些跟控件本身相關(guān)的信息堤魁。假如采用的是target+action的方式:在1.0版本喂链,有一個(gè)按鈕Button,它的處理方法是actionA妥泉,在采集埋點(diǎn)配置信息的時(shí)候椭微,生成的唯一標(biāo)識(shí)符是target+actionA。如果在2.0版本盲链,他的處理方法被修改為actionB蝇率。如果拿著這個(gè)2.0版本的target+actionB去1.0版本采集過的配置表中進(jìn)行查找迟杂,就會(huì)找不到對(duì)應(yīng)的配置項(xiàng)。那么在2.0版本中本慕,是否還需要重復(fù)采集在1.0版本采集過的埋點(diǎn)信息排拷?如果重復(fù)采集的話,這可意味著可能會(huì)有非常大的工作量间狂,一個(gè)大型App攻泼,可能全部的埋點(diǎn)個(gè)數(shù)有幾千個(gè)不等,每一個(gè)版本都把之前采集過的埋點(diǎn)在重新采集一次的話鉴象,工作量非常的可怕忙菠,也沒有必要。

還有就是纺弊,如果在2.0版本牛欢,干脆刪除了這個(gè)按鈕,那么這個(gè)按鈕的埋點(diǎn)自然也就不再需要了淆游。但是和這個(gè)按鈕相關(guān)的埋點(diǎn)配置卻不能自動(dòng)從配置表中刪除傍睹。長此以往,配置表中會(huì)冗余越來越多的無效埋點(diǎn)配置項(xiàng)犹菱,增加配置管理的成本拾稳,無論對(duì)于網(wǎng)絡(luò)還是系統(tǒng)的性能都是一個(gè)越來越嚴(yán)重的問題。

一個(gè)很有趣的現(xiàn)象是腊脱,目前市面上的可視化埋點(diǎn)方案访得,大多數(shù)沒有提到版本管理。其實(shí)版本管理陕凹,是一個(gè)必須要面對(duì)的問題悍抑。我們必須要能在版本遷移的時(shí)候,指出哪些埋點(diǎn)是繼續(xù)有效的杜耙,而哪些埋點(diǎn)已經(jīng)失效了搜骡,以供采集人員及時(shí)的更新處理。一開始我們?cè)O(shè)想佑女,通過代碼來模擬點(diǎn)擊頁面的所有元素记靡,觸發(fā)了元素的處理事件,一定會(huì)走到自動(dòng)埋點(diǎn)上報(bào)的邏輯团驱。設(shè)置一個(gè)標(biāo)識(shí)簸呈,當(dāng)在版本檢測(cè)過程中時(shí),查找到配置項(xiàng)之后店茶,不再進(jìn)行上報(bào)邏輯,而是把該配置項(xiàng)標(biāo)識(shí)為有效劫恒。代碼來模擬點(diǎn)擊頁面的元素贩幻,需要通過調(diào)用UIControl的sendAction轿腺,或者是直接調(diào)用target的action方法等。這種方式理論上可行丛楚,但是特別麻煩族壳,要處理的問題也特別多。

其實(shí)有一個(gè)很取巧的方式趣些,不需要代碼模擬點(diǎn)擊事件仿荆。循環(huán)遍歷頁面的所有元素,直接利用SDK生成這些元素的唯一標(biāo)識(shí)符坏平,然后用唯一標(biāo)識(shí)符去配置列表中查找拢操,查找到配置項(xiàng)之后該配置項(xiàng)標(biāo)識(shí)為有效。這種方案非常簡單輕巧舶替,但是也有一些問題要處理令境,比如有些視圖是在controller下面,有些視圖在window下面顾瞪,還有有一些視圖是延遲加載的舔庶,比如點(diǎn)擊了某個(gè)按鈕,然后頁面中增加一些新的元素陈醒。針對(duì)這兩個(gè)問題惕橙,我們通過設(shè)計(jì)版本檢測(cè)的交互方式來解決。在上文的SDK整體概覽的產(chǎn)品原型概覽章節(jié)钉跷,我們提到了一個(gè)檢測(cè)按鈕弥鹦。當(dāng)選擇檢測(cè)功能的時(shí)候,點(diǎn)擊頁面的某一個(gè)元素尘应,SDK會(huì)向上尋找這個(gè)元素處于的根視圖惶凝。然后從這個(gè)根視圖出發(fā),遞歸遍歷這個(gè)根視圖的所有子視圖犬钢。這樣無論視圖是在controller苍鲜,window,navigationBar下面玷犹,只要點(diǎn)擊這些地方混滔,都可以被檢測(cè)到。對(duì)于延遲加載的視圖歹颓,可以先關(guān)閉檢測(cè)按鈕坯屿,操作app把相關(guān)視圖加載出來之后,在用同樣的方式來進(jìn)行檢測(cè)巍扛。

檢測(cè)完畢后领跛,會(huì)彈出一個(gè)版本管理的視圖。按照所有埋點(diǎn)撤奸、有效埋點(diǎn)吠昭、無效埋點(diǎn)三種類型列舉出所有的配置項(xiàng)喊括。然后針對(duì)無效埋點(diǎn)進(jìn)行確認(rèn)和相關(guān)處理即可。

image.gif

總結(jié)與展望

我們的可視化埋點(diǎn)探索的技術(shù)方案先介紹到這里矢棚。對(duì)可視化埋點(diǎn)進(jìn)行過深入研究之后郑什,會(huì)發(fā)現(xiàn)上面介紹的這些問題處理起來比較困難,上面僅僅是介紹我們的方案和思考蒲肋。除了支持App發(fā)版后新增埋點(diǎn)的能力蘑拯,我們特別希望通過這種方式得到埋點(diǎn)效率提升,把開發(fā)者從體力活中解放出來兜粘。從當(dāng)下來看申窘,如果數(shù)據(jù)攜帶依然需要一系列邏輯處理的話,想通過自動(dòng)化埋點(diǎn)的方式獲得效率提升還是比較有限的妹沙。同時(shí)偶洋,把從前代碼實(shí)現(xiàn)的埋點(diǎn),替換成可視化圈選的方式距糖,雖然解決了埋點(diǎn)代碼和業(yè)務(wù)邏輯耦合的問題玄窝,但似乎像是一種人力成本的遷移,畢竟圈選采集信息還是依賴于人工處理悍引。

計(jì)算機(jī)本身的目的之一就是解決一些重復(fù)的繁瑣的事務(wù)恩脂。當(dāng)下代碼埋點(diǎn)的成本很高,不僅僅是開發(fā)者趣斤,許多方面都要投入大量的時(shí)間和精力維護(hù)俩块。所以我們相信自動(dòng)化埋點(diǎn)這個(gè)需求,會(huì)驅(qū)動(dòng)更多人持續(xù)不斷地研究浓领,不斷地提出新的思路和解決方案玉凯,最后有一天實(shí)現(xiàn)真正高效的自動(dòng)化埋點(diǎn)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末联贩,一起剝皮案震驚了整個(gè)濱河市漫仆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌泪幌,老刑警劉巖盲厌,帶你破解...
    沈念sama閱讀 222,627評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異祸泪,居然都是意外死亡吗浩,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門没隘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來懂扼,“玉大人,你說我怎么就攤上這事右蒲∥⑼酰” “怎么了屡限?”我有些...
    開封第一講書人閱讀 169,346評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長炕倘。 經(jīng)常有香客問我,道長翰撑,這世上最難降的妖魔是什么罩旋? 我笑而不...
    開封第一講書人閱讀 60,097評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮眶诈,結(jié)果婚禮上涨醋,老公的妹妹穿的比我還像新娘。我一直安慰自己逝撬,他們只是感情好浴骂,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著宪潮,像睡著了一般溯警。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上狡相,一...
    開封第一講書人閱讀 52,696評(píng)論 1 312
  • 那天梯轻,我揣著相機(jī)與錄音,去河邊找鬼尽棕。 笑死喳挑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的滔悉。 我是一名探鬼主播伊诵,決...
    沈念sama閱讀 41,165評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼回官!你這毒婦竟也來了曹宴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,108評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤孙乖,失蹤者是張志新(化名)和其女友劉穎浙炼,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體唯袄,經(jīng)...
    沈念sama閱讀 46,646評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡弯屈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了恋拷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片资厉。...
    茶點(diǎn)故事閱讀 40,861評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蔬顾,靈堂內(nèi)的尸體忽然破棺而出宴偿,到底是詐尸還是另有隱情湘捎,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布窄刘,位于F島的核電站窥妇,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏娩践。R本人自食惡果不足惜活翩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望翻伺。 院中可真熱鬧材泄,春花似錦、人聲如沸吨岭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽辣辫。三九已至旦事,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間络它,已是汗流浹背族檬。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評(píng)論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留化戳,地道東北人单料。 一個(gè)月前我還...
    沈念sama閱讀 49,287評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像点楼,于是被迫代替她去往敵國和親扫尖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容