轉自:https://juejin.im/post/5e7c7ae9f265da428e0fba12
場景
- H5頁面需要調用微信分享接口,但是在APP環境下無法通過H5去調微信分享接口,需要由APP端去調起接口,這時候H5應該如何對接APP呢?
實現思路
- 首先我們先來判斷一下當前H5所處環境,如果非APP環境下,我們走常規的微信分享方式,這裏提供一個網上通用的判斷瀏覽器、設備類型工具類
/* 判斷瀏覽器類型 */
const browser = {
versions: (function () {
var u = navigator.userAgent
return {
trident: u.indexOf('Trident') > -1, // IE內核
presto: u.indexOf('Presto') > -1, // opera內核
webKit: u.indexOf('AppleWebKit') > -1, // 蘋果、谷歌內核
gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') === -1, // 火狐內核
mobile: !!u.match(/AppleWebKit.*Mobile.*/), // 是否爲移動終端
ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), // ios終端
android: u.indexOf('Android') > -1 || u.indexOf('Adr') > -1, // android終端
iPhone: u.indexOf('iPhone') > -1, // 是否爲iPhone或者QQHD瀏覽器
iPad: u.indexOf('iPad') > -1 || u.indexOf('Macintosh') > -1, // 是否iPad
webApp: u.indexOf('Safari') === -1, // 是否web應該程序,沒有頭部與底部
weixin: u.indexOf('MicroMessenger') > -1, // 是否微信 (2015-01-22新增)
qq: u.indexOf(' QQ') > -1 // 是否QQ
}
}()),
language: (navigator.browserLanguage || navigator.language).toLowerCase()
}
// @param target 分享方式
// wx朋友:WXSceneSession = 0
// wx朋友圈:WXSceneTimeline = 1;
// @param img2Base64DataStr 圖片base64
// H5調用app分享圖片至wx朋友圈/wx朋友
function shareImageToWx (target, img2Base64DataStr) {
if (browser.versions.ios || browser.versions.iPad) {
window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.shareImage2Wx.postMessage({
target: target,
img2Base64DataStr: img2Base64DataStr
})
} else {
window.android && window.android.shareImage2Wx(target, img2Base64DataStr)
}
}
- h5頁面與IOS交互
- WKWebView 是 iOS 8 之後提供的一款瀏覽器組件,使用WKWebView的時候,如果想要實現JS調用OC方法,除了攔截URL之外,還有一種簡單的方式。那就是利用WKWebView的新特性MessageHandler來實現JS調用原生方法。
- window.webkit.messageHandlers.<name>.postMessage(<messageBody>)
- name爲ios那邊聲明的方法名(上例爲調起微信分享的函數名)
- messageBody爲傳參,需要藉助postMessage進行傳遞,具體數據結構看ios端定義
- h5頁面與Android交互
- window.android.<name>(<messageBody>)
- android端則比較簡單,客戶端註冊方法到window上供h5調用即可
- name爲android那邊聲明的方法名(上例爲調起微信分享的函數名)
- messageBody爲傳參,具體數據結構看android端定義
- 客戶端調用H5頁面裏定義的js方法
mounted() {
// 將getData方法綁定到window下面,這個函數名提供給客戶端調用,定義接收參數(具體看實際場景)
window['getData'] = (data) => {
this.handleData(data)
}
},
methods: {
handleData(data) {
// to do something
}
}
小插曲
- 在ipad6 APP環境下的測試機進行測試的時候,發現無法調用客戶端接口,摸索後發現ipad在安裝ios13版本後出現一個詭異的問題(BUG ?):navigator.userAgent中不帶ipad字段,通用的工具類函數判斷ipad設備出現問題,無法通過indexOf(‘iPad’)去判斷設備爲ipad,需要增加Macintosh作爲識別ipad設備的條件(開頭的工具類我已經寫進去)
- 當WebView寬度設置超過375的時候,UA:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko)
- 當WebView寬度設置低於375的時候,UA:
Mozilla/5.0 (iPad; CPU OS 13_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148