隨着大數據時代的到來,數據採集也已經變的愈來愈重要。前端埋點做爲一個比較成熟的數據接入手段被普遍應用着。目前埋點分爲兩種方式,有碼與無碼埋點。有碼埋點比較容易理解,即調用SDK的API,在代碼中插入埋點的相關代碼,實現用戶行爲採集。因爲咱們在開發項目的時候,埋點都是手動的,每次業務需求的改變都要處處埋點,而無碼埋點,即不須要手動插入代碼,只須要前期進行相關配置,SDK自動採集用戶行爲,極大程度避免了因需求變動、埋點錯誤等緣由致使的從新埋點繁複工做。本文主要介紹無碼埋點的技術實現。前端
無碼埋點的實現流程數組
1.可視化視圖圈選,在頁面上會出現浮動的圓圈,拖動圓圈至想配置事件的控件上,將會彈出輸入事件的彈框。
2.在上一步的彈框中輸入自定義的事件名稱,名稱將會和視圖的viewPath綁定起來。viewPath是視圖的惟一標識,在下文中將詳細講解。
3.用戶點擊了控件,判斷控件是否綁定過事件,如綁定則進行事件上傳。大數據
實現流程中的技術點spa
可視化視圖圈選實現代理
自定義UIWindow的子類,當作懸浮小圓圈,添加UIPanGestureRecognizer手勢,根據手勢的位移,設置懸浮框的位移。手勢中止時獲取懸浮窗中心點的座標。
遍歷主window上的子視圖,找到包含上述懸浮窗中心點且能響應用戶交互的最裏層視圖,即爲用戶能夠圈選的視圖。
參考iOS控件的消息傳遞鏈,有個核心方法。UIView hitTest:(CGPoint)point withEvent:(UIEvent *)event。此API自動遍歷子視圖,找到包含point的視圖,event傳nil。因爲event參數是nil,最終找到的視圖並不必定是能響應用戶手勢的視圖,若是不能響應則遍歷其父視圖,直到找到能響應用戶行爲的視圖。對象
圈選視圖綁定事件事件
視圖惟一標識viewPath生成,上述步驟已經拿到了圈選的視圖。如何肯定視圖的viewPath也是重點。viewPath須要整個應用惟一,才能夠區別不一樣的事件。因爲是無碼,因此只能從視圖自己的屬性去分析。咱們能夠把App的視圖結構理解成樹的概念,樹的根節點是UIWindow,樹的枝幹由UIViewController和UIView組成,葉子節點都是UIView。那麼從根節點到葉子節點的路徑能夠看作是惟一的。也就是視圖的viewPath。下面介紹下實現的邏輯,viewPath由兩部分組成,第一部分是節點路徑,另外一部分是與之對應的節點index。節點路徑是由每一個節點的Class拼接而成,節點index,就是節點在父節點中的下標,好比子視圖在父視圖的subviews數組中的下標。下圖是遍歷節點的邏輯圖。
計算節點的index,這個步驟,有種特殊的視圖須要注意,可複用視圖的index是跟數據源相關的,好比UITableViewCell,此類視圖的index不能使用父視圖的subviews的下標代替,應該使用數據源的下標表明,好比cell的indexPath.section:indexPath.row。下面給出一個簡單視圖和可複用視圖的viewPath的例子。TestViewController-UIView-UIButton&0-0-0和TableViewController-UITableView-UITableViewCell&0-0-1:0。
如何檢測用戶觸發了綁定了事件ID的視圖也是重點,此處運用的核心技術是runtime中Method Swizzle。下面介紹一下針對不一樣類型的控件,如何hook相應的方法。圖片
總結開發
無碼埋點的關鍵技術,就是以上分析的幾點,首先經過可視化圈選拿到須要綁定事件視圖,並生成惟一標識viewPath,經過hook系統控件的方法,拿到用戶觸發的視圖,生成視圖的viewPath與本地的事件列表比對,比對成功則上傳viewPath對應的事件。get
本文原創首發於Cobub官網博客,轉載請註明出處!