uniapp增加自定義埋點功能

起因

首先來說,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好了:

好了,一切完畢,終於成功撒花!!!

結尾

雖然看這一系列的過程很簡單,但是礙於實力,當時確實小小的折騰了一把,記錄下來,如果有後來者操作到類似,也可以當個參考。