H5与iOS/Android交互
转载
场景
- 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)
}
}
- WKWebView 是 iOS 8 之后提供的一款浏览器组件,使用WKWebView的时候,如果想要实现JS调用OC方法,除了拦截URL之外,还有一种简单的方式。那就是利用WKWebView的新特性MessageHandler来实现JS调用原生方法。
- window.webkit.messageHandlers.<name>.postMessage(<messageBody>)
- name为ios那边声明的方法名(上例为调起微信分享的函数名)
- messageBody为传参,需要借助postMessage进行传递,具体数据结构看ios端定义
- window.android.<name>(<messageBody>)
- android端则比较简单,客户端注册方法到window上供h5调用即可
- name为android那边声明的方法名(上例为调起微信分享的函数名)
- messageBody为传参,具体数据结构看android端定义
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