uniapp增加自定義埋點功能

可飛發表於2021-11-29

起因

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

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

結尾

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

相關文章