起因
首先來說,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好了:
好了,一切完畢,終於成功撒花!!!
結尾
雖然看這一系列的過程很簡單,但是礙於實力,當時確實小小的折騰了一把,記錄下來,如果有後來者操作到類似,也可以當個參考。