uniapp增加自定義埋點功能
- 2021 年 11 月 29 日
- 筆記
- javascript
起因
首先來說,uniapp其實是自帶系統埋點統計功能的。基本也算是面面俱到。
但是一些未知原因,貌似數據有所丟失,再加上沒有一些重要的訂製化功能,以及最重要的數據安全方面的考慮,還是決定接入公司的埋點應用。
過程
uniapp用的vue做前端開發,而我們這埋點應用其實只適用於web端,直接在vue里引入肯定是不行的,而且這埋點的js還不是模組化應用,根本無法直接導入應用。
如果要用這套埋點的js,那沒辦法,思前想後,必然要用到webview內嵌一個靜態h5來使用。先看下uniapp的目錄結構:
在hybrid目錄下,新建local.html,頁面中引入對應的埋點js後,並且初始化。
其次在APP主頁面上用web-view控制項進行引入,如下:
<web-view src="../../hybrid/html/local.html"></web-view>
問題來了,這web-view引入後,確實是能用的,但是只能用一次。我這埋點是想要查看用戶的APP頁面軌跡,這樣只導入的時候執行一次,明顯是不符合要求。為此還特意諮詢了下埋點的同事,但是他們好像也沒接uniapp的相關應用,好吧,我又成第一個吃螃蟹的人了:
沒辦法,硬著頭皮翻翻文檔吧,其實我還是有思路的,VUE就是一個大的單頁應用,其實多個頁面只要不刷新,理論上應該是可以相互通訊的,那既然如此這個webView的句柄拿到手是不是就可能做到通訊了?
帶著問題找官方文檔,得知確實是可以的:
App端的webview是非常強大的,可以更靈活的控制和擁有更豐富的API。
每個vue頁面,其實都是一個webview,而vue頁面里的web-view組件,其實是webview里的一個子webview。這個子webview被append到父webview上。
既然如此,我就定義一個全局對象來保存這個句柄。程式碼如下:
globalData: {
VUE_APP_MD:''
}
let wv=this.$scope.$getAppWebview().children()[0]
wv.hide()
getApp().globalData.VUE_APP_MD = wv
現在句柄是拿到了,剩下的就是通訊了。
還是查看官網文檔,終於找到了這個evalJS:
有了evalJS就解決了通訊的問題,剩下的就是在所有頁面的調用的時候,加一波橫向業務擴展,這邊用到uni插件市場的router插件,在後置方法里增加了調用埋點api的邏輯,具體如下:
// 全局路由後置守衛
router.afterEach((to, from) => {
if(getApp().globalData.VUE_APP_MD){
getApp().globalData.VUE_APP_MD.evalJS('test.trackEvent("c_1",{' +
'c_user_mobile:"'+uni.getStorageSync("userInfo").mobile+'",' +
'c_url_path:"'+to.path+'",' +
'c_suppl_id:"'+uni.getStorageSync("supplId")+'",' +
'c_url_c_name:"'+(to.query.title?to.query.title:"")+'"' +
'})')
}
})
試了下,果然成功拿到數據。似乎馬上就要成功了,但是在ios上用的時候,發現竟然用不了,測試發現竟然不支援跨域操作。
這裡面東東真多,IOS的內核是WKWebview內核,竟然還不支援跨域,HBuilderX 2.2.5+版本已將iOS上所有webview的默認內核由UIWebview調整為WKWebview。至於兩者內核的區別,官網寫的很詳細:
解決方案也很簡單,那就切換成UIWebview好了:
好了,一切完畢,終於成功撒花!!!
結尾
雖然看這一系列的過程很簡單,但是礙於實力,當時確實小小的折騰了一把,記錄下來,如果有後來者操作到類似,也可以當個參考。