起因

首先来说,uniapp其实是自带系统埋点统计功能的。基本也算是面面俱到。

uniapp ios 安卓友盟埋点 uniapp埋点方案_webview

但是一些未知原因,貌似数据有所丢失,再加上没有一些重要的定制化功能,以及最重要的数据安全方面的考虑,还是决定接入公司的埋点应用。

过程

uniapp用的vue做前端开发,而我们这埋点应用其实只适用于web端,直接在vue里引入肯定是不行的,而且这埋点的js还不是模块化应用,根本无法直接导入应用。

如果要用这套埋点的js,那没办法,思前想后,必然要用到webview内嵌一个静态h5来使用。先看下uniapp的目录结构:

uniapp ios 安卓友盟埋点 uniapp埋点方案_uniapp ios 安卓友盟埋点_02

在hybrid目录下,新建local.html,页面中引入对应的埋点js后,并且初始化。

其次在APP主页面上用web-view控件进行引入,如下:

<web-view src="../../hybrid/html/local.html"></web-view>

问题来了,这web-view引入后,确实是能用的,但是只能用一次。我这埋点是想要查看用户的APP页面轨迹,这样只导入的时候执行一次,明显是不符合要求。为此还特意咨询了下埋点的同事,但是他们好像也没接uniapp的相关应用,好吧,我又成第一个吃螃蟹的人了:

uniapp ios 安卓友盟埋点 uniapp埋点方案_html_03

没办法,硬着头皮翻翻文档吧,其实我还是有思路的,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:

uniapp ios 安卓友盟埋点 uniapp埋点方案_uniapp ios 安卓友盟埋点_04

有了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。至于两者内核的区别,官网写的很详细:

uniapp ios 安卓友盟埋点 uniapp埋点方案_uniapp ios 安卓友盟埋点_05

解决方案也很简单,那就切换成UIWebview好了:

uniapp ios 安卓友盟埋点 uniapp埋点方案_html_06

好了,一切完毕,终于成功撒花!!!

结尾

虽然看这一系列的过程很简单,但是碍于实力,当时确实小小的折腾了一把,记录下来,如果有后来者操作到类似,也可以当个参考。