ta);
delete responseCallbacks[message.responseId];
} else {
//否则,代表原生主动执行h5本地的函数
if(message.callbackId) {
//先判断是否需要本地H5执行回调函数
//如果需要本地函数执行回调通知原生,那么在本地注册回调函数,然后再调用原生
//回调数据有h5函数执行完毕后传入
var callbackResponseId = message.callbackId;
responseCallback = function(responseData) {
//默认是调用EJS api上面的函数
//然后接下来原生知道scheme被调用后主动获取这个信息
//所以原生这时候应该会进行判断,判断对于函数是否成功执行,并接收数据
//这时候通讯完毕(由于h5不会对回调添加回调,所以接下来没有通信了)
_doSend({
handlerName: message.handlerName,
responseId: callbackResponseId,
responseData: responseData
});
};
}
//从本地注册的函数中获取
var handler = messageHandlers[message.handlerName];
if(!handler) {
//本地没有注册这个函数
} else {
//执行本地函数,按照要求传入数据和回调
handler(message.data, responseCallback);
}
}
}
}
};
/**
* @description JS调用原生方法前,会先send到这里进行处理
* @param {JSON} message 调用的方法详情,包括方法名,参数
* @param {Function} responseCallback 调用完方法后的回调
*/
function _doSend(message, responseCallback) {
if(responseCallback) {
//取到一个唯一的callbackid
var callbackId = Util.getCallbackId();
//回调函数添加到集合中
responseCallbacks[callbackId] = responseCallback;
//方法的详情添加回调函数的关键标识
message['callbackId'] = callbackId;
}
var uri;
//android中,可以通过onJsPrompt或者截取Url访问都行
var ua = navigator.userAgent;
if(ua.match(/(iPhone\sOS)\s([\d_]+)/)||ua.match(/(iPad).*OS\s([\d_]+)/)) {
//ios中,通过截取客户端url访问
//因为ios可以不暴露scheme,而是由原生手动获取
//正在调用的方法详情添加进入消息队列中,原生会主动获取
sendMessageQueue.push(message);
uri = Util.getUri();
}else{
//android中兼容处理,将所有的参数一起拼接到url中
uri = Util.getUri(message);
}
//获取 触发方法的url scheme
//采用iframe跳转scheme的方法
messagingIframe.src = uri;
}
var Util = {
getCallbackId: function() {
//如果无法解析端口,可以换为Math.floor(Math.random() * (1 << 30));
return 'cb_' + (uniqueId++) + '_' + new Date().getTime();
},
//获取url scheme
//第二个参数是兼容android中的做法
//android中由于原生不能获取JS函数的返回值,所以得通过协议传输
getUri: function(message) {
var uri = CUSTOM_PROTOCOL_SCHEME + '://' + API_Name;
if(message) {
//回调id作为端口存在
var callbackId, method, params;
if(message.callbackId) {
//第一种:h5主动调用原生
callbackId = message.callbackId;
method = message.handlerName;
params = message.data;
} else if(message.responseId) {
//第二种:原生调用h5后,h5回调
//这种情况下需要原生自行分析传过去的port是否是它定义的回调
callbackId = message.responseId;
method = message.handlerName;
params = message.responseData;
}
//参数转为字符串
params = this.getParam(params);
//uri 补充
uri += ':' + callbackId + '/' + method + '?' + params;
}
return uri;
},
getParam: function(obj) {
if(obj && typeof obj === 'object') {
return JSON.stringify(obj);
} else {
return obj || '';
}
}
};
for(var key in Inner) {
if(!hasOwnProperty.call(JSBridge, key)) {
JSBridge[key] = Inner[key];
}
}
|