H5與iOS/Android交互

轉自: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()
}
  • 我們需要聲明一套針對APP場景下的js函數
// @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方法
    • 這裏用vue作爲例子
   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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章