js-bridge 异步通信

1,045 阅读1分钟

客户端 有IOSAndriod两个版本,与 H5的通信都是异步的,具有很强的通用性,可写成通用的。

协议说明

通信对象:micoJsBridge

Android调用方式:

window
.webkit
.micoJsBridge
.postMessage(
  '{"action":"接口标识,必传", "response":"回调方法名,非必传", "data":"参数, 非必传"}'
);

IOS调用方式:

window
.webkit
.messageHandlers
.micoJsBridge
.postMessage(
  '{"action":"接口标识,必传", "response":"回调方法名,非必传", "data":"参数, 非必传"}'
 );

回调

回调异步。

response('{"action":"接口标识,  code: 错误码, 0表示成功, 非必传, "data":"参数, 非必传"}')
// 例子 
{
    "code":0,
    "data":"{
    	"deviceid":"435c4f26-e9a2-4927-bcd0-098b80616d4e",
    	"userid":"108676918",
    	"authorization":"AO-TOKEN-V1",
    	"dev_app_id":"dev_app_id"
    }"
}

host环境判断

const isAndriod = 
  !!(window.webkit 
  && window.webkit.micoJsBridge 
  && window.webkit.micoJsBridge.postMessage)
  
const isIOS = 
  !!(window.webkit 
  && window.webkit.messageHandlers 
  && window.webkit.messageHandlers.micoJsBridge 
  && window.webkit.messageHandlers.micoJsBridge.postMessage)
 
const isInNative =  isAndriod || isIOS

执行方法

let invoke = v => {  console.log('没有执行环境',v) }
// 注意这里的细节
if(isAndriod){
  invoke = v => window.webkit.micoJsBridge.postMessage(v)
}else if(isIOS){
  invoke = v => window.webkit.messageHandlers.micoJsBridge.postMessage(v)
}

执行动作

const sendAction = (action, data = {}) => new Promise(resolve, reject)
{
     const id = (+new Date()).toString()
     const callbackName = action + id
     window[callbackName] = data => {
      if(data.code === 0){
         // 执行成功
        if (typeof data.data === 'string'){
          try {
            resolve(JSON.parse(data.data))
          } catch (error) {
            reject(error)
          }
        }else{
          resolve()
        }
      }else{
        reject(data)
      }
      delete window[callbackName]
    }
    
    let requestStr = JSON.stringify({
        action,
        response: callbackName,
        ...data
      }
    )
    invoke(requestStr)
}

调用例子

sendAction('getUserAuthorizationInfo').then(data => console.log(data))

方法不一致时候

const invoke = async function (xiaoai, lite) {
    if (env.isXiaoAI && Array.isArray(xiaoai) && xiaoai.length > 0) {
        const [xiaoaiMethod, params, formater = loop] = xiaoai
        const data = await App.xiaoaiInvoke(xiaoaiMethod, params)
        return formater(data)
    } else if (env.isLite && Array.isArray(lite) && lite.length > 0) {
        const [liteMethod, params, liteFormater = loop] = lite
        const data = await App.liteInvoke(liteMethod, params)
        return liteFormater(data)
    }
    return undefined
}

    const { userId, deviceId, appId: web_app_id, dialogId } = await invoke(['xiaoai.getUserInfo', undefined, JSON.parse]) || {}