WebViewJavascriptBridge 结合源码原理分析

前言

WebViewJavascriptBridge(v6.0.3)作为现在混合App使用最为广泛的JSBridge桥接库,这篇文章主要结合源码解析其工作流程。

基本原理

Native 和 JavaScript 的交互一般是通过以下三种方式实现的
1、(UIWebView)Native 通过 -stringByEvaluatingJavaScriptFromString: 执行一段js代码
2、(WKWebView)Native通过 -evaluateJavaScript:方法执行一段js代码
3、JavaScript to Native:在网页中加载一个 Custom URL Scheme 的链接(设置 window.location 或新建一个 iframe 去加载这个 URL),原生在代理方法拦截处理
3、iOS使用JavaScriptCore

WebViewJavascriptBridge 是使用了方式1和2 或者 1和3 来完成的

API

原生

//注册方法,在JS调用原生时调用
- (void)registerHandler:(NSString*)handlerName handler:(WVJBHandler)handler;
//调用js注册过的方法,
- - (void)callHandler:(NSString*)handlerName;
- (void)callHandler:(NSString*)handlerName data:(id)data;
- (void)callHandler:(NSString*)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback;

JavaScript

// 注册方法,以方法名为key handler 为值,保存到messageHandlers 中
function registerHandler(handlerName, handler) {
		messageHandlers[handlerName] = handler;
}

// 调用方法
function callHandler(handlerName, data, responseCallback) {
		if (arguments.length == 2 && typeof data == 'function') {
			responseCallback = data;
			data = null;
		}
		_doSend({ handlerName:handlerName, data:data }, responseCallback);
}

// 提供给原生调用
function _fetchQueue() {
		var messageQueueString = JSON.stringify(sendMessageQueue);
		sendMessageQueue = [];
		return messageQueueString;
}

交互流程

WebViewJavascriptBridge 参与交互的流程包括三个部分:JS端初始化、原生初始化、JS 调用原生、原生调用 JS。

1、JS端初始化:

在这里插入图片描述
1.1、网页第一次加载就会执行 web 页中的 bridge 初始化代码,也就是调用上面提到的 setupWebViewJavascriptBridge(bridge)函数
1.2、通过添加一个 iframe 加载初始化链接 https://bridge_loaded
1.3、原生 WebViewJavascriptBridge 类中代理方法会拦截 https://bridge_loaded 的加载
1.4、原生执行 -injectJavascriptFile 方法 把 WebViewJavascriptBridge_js文件字符串注入到_webView中
1.5、初始化完成

2、原生初始化(iOS)

在这里插入图片描述

3、JS调用原生

1、原生注册
- (void)registerHandler:(NSString *)handlerName handler:(WVJBHandler)handler {
    _base.messageHandlers[handlerName] = [handler copy];
}
注册方法保存到WebViewJavascriptBridgeBase中的messageHandlers字典 方法名为key  WVJBHandler block 为值

2、JS端调用全局对象window.webViewJavascriptBridge对象调用初始化注入的方法
function callHandler(handlerName, data, responseCallback)
(注:WebViewJavascriptBridge_JS中的方法,js初始化加载注入)

3、JS把把方法保存到消息数组 sendMessageQueue中
保存格式:
{ "handleName": handleName",
  "data": data,
  "callbackId": responseCallback
}
4、JS利用 messagingIframe.src = https://__wvjb_queue_message__  触发iframe 加载发送消息的 URL,原生拦截到 https://__wvjb_queue_message__ 利用 _evaluateJavaScript方法执行JS代码 WebViewJavascriptBridge._fetchQueue();
- (void)WKFlushMessageQueue {
    [_webView evaluateJavaScript:[_base webViewJavascriptFetchQueyCommand] completionHandler:^(NSString* result, NSError* error) {
        if (error != nil) {
            NSLog(@"WebViewJavascriptBridge: WARNING: Error when trying to fetch data from WKWebView: %@", error);
        }
        [_base flushMessageQueue:result];
    }];
}

5、在JS端全局对象 WebViewJavascriptBridge的_fetchQueue()方法
	function _fetchQueue() {
		var messageQueueString = JSON.stringify(sendMessageQueue);
		sendMessageQueue = [];
		return messageQueueString;
	}
获取到刚才保存到sendMessageQueue消息队列中的参数
	
6、利用原生注册的方法回调给上层应用

4、原生调用JS

1、JS注册方法
	function registerHandler(handlerName, handler) {
		messageHandlers[handlerName] = handler;
	}
	保存到messageHandlers字典中
2、原生调用
- (void)callHandler:(NSString *)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback {
    [_base sendData:data responseCallback:responseCallback handlerName:handlerName];
}
把参数生成message字典
格式:
{ "handlerName": handlerName,
  "callbackId": callbackId,
  "data":data
}
再调用- (void)_dispatchMessage:(WVJBMessage*)message  方法
把message格式化成json字符串messageJSON 生成js字符串代码
NSString* javascriptCommand = [NSString stringWithFormat:@"WebViewJavascriptBridge._handleMessageFromObjC('%@');", messageJSON];

利用_webview方法 [_webView evaluateJavaScript:javascriptCommand completionHandler:nil]; 执行JS全局对象中的 _handleMessageFromObjC 方法

3、在js的全局对象中执行 _handleMessageFromObjC 方法,根据原生传入的参数 messageJSON解析出 data, callbackid, handleName

4、根据callbackId 执行回调,根据handleName 在messageHandlers字典中找出js注册的方法,执行js方法,带入data参数

5、js接收到原生的参数,处理相应的逻辑

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值