深入理解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,回调是如何执行的?