移动端h5与原生交互JSBridge初体验

1.移动端判断终端

const ua = window.navigator.userAgent.toLowerCase()

// android平台
const isAndroid = (() => {
  return /Android|Adr/i.test(ua)
})()

// ios平台
const isIos = (() => {
  return /iPhone|iPod|iPad/i.test(ua)
})()

// 微信生态
const isWechat = (() => {
  return /MicroMessenger/i.test(ua)
})()

// 微信小程序
const isWxmp = (() => {
  return /miniProgram/i.test(ua) || window.__wxjs_environment === 'miniprogram'
})()

export default {
  isAndroid,
  isIos,
  isWechat,
  isWxmp,
}

2. 全局封装jsBridge

import Vue from 'vue'
import { Toast } from 'vant'
import UA from './platform'

const TIMEOUT = 2000

const timeoutPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(new Error('JsBridge timeout'))
  }, TIMEOUT)
})

const connectWebViewJavascriptBridge = function () {
  const promise = new Promise((resolve, reject) => {
    let callback = () => resolve(window.WebViewJavascriptBridge)

    if (UA.isAndroid) {
      if (window.WebViewJavascriptBridge) {
        return callback()
      }
      document.addEventListener('WebViewJavascriptBridgeReady', callback, false)
    } else if (UA.isIos) {
      if (window.WebViewJavascriptBridge) {
        return callback()
      }
      if (window.WVJBCallbacks) {
        return window.WVJBCallbacks.push(callback)
      }
      window.WVJBCallbacks = [callback]
      var WVJBIframe = document.createElement('iframe')
      WVJBIframe.style.display = 'none'
      WVJBIframe.src = 'https://__bridge_loaded__'
      document.documentElement.appendChild(WVJBIframe)
      setTimeout(function () {
        document.documentElement.removeChild(WVJBIframe)
      }, 0)
      sessionStorage.phoneType = 'ios'
    } else {
      reject(new Error('JsBridge need in app environment!'))
    }
  })

  return Promise.race([promise, timeoutPromise])
}

const Bridge = {
  async init() {
    let bridge
    try {
      bridge = await connectWebViewJavascriptBridge()
      console.log('bridge: ', bridge)
      bridge.init(function (message, responseCallback) {
        responseCallback({ 'Javascript Responds': 'Wee!' })
      })
    } catch (error) {
      console.error(error.message)
    }
  },
  async callhandler(data) {
    let bridge
    try {
      bridge = await connectWebViewJavascriptBridge()
      const promise = new Promise((resolve, reject) => {
        const callName = 'JsCallApp'

        bridge.callHandler(callName, data, (res) => {
          try {
            res = JSON.parse(res)
            let resData = res.appToJs[data.type]
            resolve(resData)
          } catch (error) {
            reject(error)
          }
        })
      })
      return Promise.race([promise, timeoutPromise])
    } catch (error) {
      return Promise.reject(error)
    }
  },
  async registerhandler(name, callback) {
    const registerName = 'AppCallJs'
    const bridge = await connectWebViewJavascriptBridge()
    bridge.registerHandler(registerName, function (data, responseCallback) {
      try {
        let res = JSON.parse(data)
        if (res.type === name) callback(data, responseCallback)
      } catch (error) {
        Toast(error.massage || 'jsBridge Error')
      }
    })
  },
}

Bridge.init()

Vue.prototype.$Bridge = Bridge

export default Bridge

3.h5通信app

 demo

     this.$Bridge.callhandler({
        type: 'file_preview',
        jsToApp: {
          files: [
            {
              download_url: 'http://www.baidu.com'
            }
          ]
        }
      })

4.app通信h5

     this.$Bridge.registerhandler('MICROLECTURE_h5', res => {
        const data = JSON.parse(res)
        console.log(data)
      })

 

你可能感兴趣的:(jsbridge,移动端交互,android,ios,html5,vue.js)