WebViewJavascriptBridge的github地址
WebViewJavascriptBridge的基本原理
在WebViewJavascriptBridge.m的文件重写了UIWebView的shouldStartLoadWithRequest:navigationType
方法,此方法在html页面的js动作触发时、url变化的时、网页内容变化的时会自动调用。
1 | - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { |
js调用oc方法
总结:
1.首先是在UIViewController 里面实例化 一个bridge 通过bridge 注册一个 handler 然后保存在messageHandlers中
2.点击网页的button的时候 把信息保存起来生成一个message 字典 三个key(handlerName , data,callbackId(后边通过这个来找到之前的responseCallback方法)) 并且把 其中的responseCallback 保存起来,并且改变iframe.src(改变iframe.src会执行shouldStartLoadWithRequest:navigationType
方法)
3.这个时候 webView 执行代理方法,在这里面取出2步存起来的信息 然后给1步的handler中的responseCallback赋值,并且执行 1步注册的方法
所以结果就是 执行oc的回调方法 然后在oc的回调方法里面再去执行 刚刚被赋值的 responseCallback方法(这个方法的响应结果体现在web中)至于这个responseCallback被赋值的过程就是通过第二步的callbackId 找到相应的方法赋过去。
oc调用js方法
1.如果有callbakId存在 那么就给实现 responseCallback 这个方法(并不调用)
2 如果message.handlerName存在 那么就取出messageHandlers中 message.handlerName 对应的方法 这个方法一般是在js代码中注册过的。
注册方法
1 | bridge.registerHandler('testJavascriptHandler', function(data, responseCallback) { |
这里最后 如果既有handler 又有callback 就会把第一步实现的方法赋值给handler的 responseCallback 然后在执行到handler的最后一句 responseCallback(responseData) 时候 再执行 执行这个回调。
JS端如何使用
JS端代码,我是直接复制了Demo里面的代码。
1 | <!doctype html> |
在JS端,嵌入步骤是:
第一步:将下面的代码放在JS中:
1 | <!--这段代码是固定的,必须要放到js中的,应该是js注册WebViewJavascriptBridge的--> |
这段代码是固定的,必须要放到js中。
1 | setupWebViewJavascriptBridge(function(bridge) { |
JS如何调用iOS代码
通过bridge.callHandler来调用:
1 | bridge.callHandler('testObjcCallback', {'foo': 'bar'}, function(response) { |
其中,各参数说明如下:
testObjcCallback:是iOS端register的handleName,在iOS端注册后,JS就可以直接通过这个handleName与iOS交互。比如,当点击某个按钮时,就执行上面这一段代码,结果就是js端将参数传给了iOS端,iOS端收到参数,然后通过回调给js,js会收到response,然后打印出来。
{‘foo’: ‘bar’}这是JSON字符串,传到iOS端会被WebViewJavascriptBridge自动转换成id对象,然后在回调处看到的就是字典对象了。
function(response)这是个js函数,在iOS端收到回调后,拿到了参数,然后通过闭包回调反馈给js端,这个反馈就是通过js函数来传值给js。
###JS端加入WebViewJavascriptBridge代码注意事项
如果在下面的函数体内有任何错误,都不会有打印日志,也不会有任何回调:
1 | setupWebViewJavascriptBridge(function(bridge) { |
因此,如果遇到什么也没有输出,说明你写错了。另外,上面有demo中,log函数是自定义的,不是系统的,因此如果没有加入这个函数的定义,调用它也会导致不能交互。
iOS端如何使用
第一步:开启日志
1 | // 开启日志,方便调试 |
第二步:给ObjC与JS建立桥梁
1 | // 给哪个webview建立JS与OjbC的沟通桥梁 |
第三步:注册HandleName,用于给JS端调用iOS端
1 | // JS主动调用OjbC的方法 |
第四步:直接调用JS端注册的HandleName
1 | //需要传给JS端的数据 |
源代码
这篇博客用的是GitHub上原版的Demo写的,需要看源码的直接下载官方demo对照着看就可以了。