Alisa

做一个简单自强的人

主页 随笔

深入理解WebViewJavascriptBridge

一. iOS和JS交互的方式

1. Native调用JS

1.1 直接调用stringByEvaluatingJavaScriptFromString

返回值单一,如果返回其它数据类型,需要进行转换,不够灵活 js报错和无返回值都返回nil,无法区分

1.2 JavascriptCore

JavascriptCore 一直作为WebKit中内置的JS引擎使用,在iOS7之后,Apple对原有C/C++代码进行了OC封装,成为了系统级的framewok提供给开发者使用,举例如下
通过KVC拿到js执行的上下文JSContext,然后通过js上下文调用evaluateScript来达到调用JS的目的
JSValue是任意类型数据,解决上面直接调用stringByEvaluatingJavaScriptFromString返回值单一问题
通过setExceptionHandler来捕获js的执行异常

2. JS调用OC

2.1 通过设置URL Scheme

2.2 利用JavaScriptCore,需要页面加载完成,获取js上下文,然后进行方法映射代码示例如下

在iOS8中,Apple引入了新一代的WebKit framework,同时提供了WKWebView用来替代传统的UIWebView。
它更加的稳定、拥有60fps滚动刷新率、丰富的手势、KVO、高效的Web和Native通信,默认进度条等等功能,而最重要的,是使用了和safari相同的Nitro引擎极大提升了Javascript的运行速度。
WKWebView独立的进程管理,也降低了内存占用及Crash对主App的影响。

3. OC调用JS

WKWebView提供一个类似于JavaScriptCore的方法
该方法很好的解决了UIWebVIew使用stringByEvaluatingJavaScriptFromString方法的两个缺点(1.返回值单一 2.报错无法捕获),
例如想获取某页面的title

4. JS调用OC

4.1 URL Scheme拦截,用法与UIWebView一致

4.2 使用addScriptMessageHandler注册的方式

二. 原理解析

1. Tips

#define __wvjb_js_func__(x) #x 宏定义中#号的意思是将参数字符传化
;(function() {})() 这是一个会立即执行的匿名函数,主要目的是为了创建一个函数作用域,约束匿名函数中的变量,避免污染全局作用域

https://__bridge_loaded__

2. 问题

WebViewJavascriptBridge 哪来的?

WVJBCallbacks的作用?

为什么创建WVJBIframe,他的作用是什么?

JS如何调用Native,回调是如何执行的?

Native如何调用JS,回调是如何执行的?

3. 思维导图