前言
目前大部分的APP或多或少都会嵌入HTML界面,这时候就需要Obj-C跟Javascript进行交互了。下面给大家介绍一下一个比较流行的开源交互框架,这个框架实现了在UIWebView和WKWebView下Obj-C和Javascript之间的交互。
原理
关于其实现的原理其实我也理解的不是很透彻,只知道它还是基于之前的Obj-C与Javascript交互的老方法:JS调用Obj-C是通过对webview的请求进行拦截,然后决定是进行网页界面跳转还是调Obj-C本地方法。具体可以看下我这篇文章
使用
一.准备工作:前往github下载源代码
可手动拖入工程,也支持cocoapod,我现在用的是V5.0.5版本,里面文件如下
源文件二.具体使用
1.导入头文件,并声明一个WebViewJavascriptBridge对象。
#import <WKWebViewJavascriptBridge.h>
@property (nonatomic, strong) WebViewJavascriptBridge* bridge;
2.创建一个WebView,并用WebViewJavascriptBridge对象绑定这个Webview,在控制器中遵守UIWebViewDelegate。
#pragma mark - Lazy
- (UIWebView *)webView {
if(_webView == nil) {
_webView = [[UIWebView alloc] init];
[self.view addSubview:_webView];
_webView.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"ExampleApp" ofType:@"html"];
NSString* appHtml = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil];
NSURL *baseURL = [NSURL fileURLWithPath:htmlPath];
[_webView loadHTMLString:appHtml baseURL:baseURL];
}
return _webView;
}
- (WebViewJavascriptBridge *)bridge {
if(_bridge == nil) {
_bridge = [[WebViewJavascriptBridge alloc] init];
//[WebViewJavascriptBridge enableLogging];
_bridge = [WebViewJavascriptBridge bridgeForWebView:self.webView];
[_bridge setWebViewDelegate:self];
}
return _bridge;
}
3.JS端的配置工作
下面这个方法是必须添加的
<script>
function setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
window.WVJBCallbacks = [callback];
var WVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
}
</script>
4.Obj-C调用JS
在需要进行交互的界面中由JS注册方法供Obj-C调用
setupWebViewJavascriptBridge(function(bridge) {
bridge.registerHandler('ObjCCallJS', function(data, responseCallback){ console.log("JS Received:", data) responseCallback(data)
})
})
Obj-C主动去调用JS方法
//不传参
[self.bridge callHandler:@"ObjCCallJS"];
//传参数
[self.bridge callHandler:@"ObjCCallJS" data:@{@"key":@"value"}];
//传参数并接收JS回调内容
[self.bridge callHandler:@"ObjCCallJS" data:@{@"key":@"value"} responseCallback:^(id responseData) {
//data:你传给JS的内容
//responseData:JS被Obj-C调用后,回调给Obj-C的内容
}];
5.JS调用Obj-C
Obj-C注册方法供JS调用
//请求打电话
[self.bridge registerHandler:@"callNativeCall" handler:^(id data, WVJBResponseCallback responseCallback) {
NSMutableString * telstr=[[NSMutableString alloc] initWithFormat:@"telprompt://%@",data[@"tel"]];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:telstr]];
}];
JS主动去调用Obj-C注册好的方法
setupWebViewJavascriptBridge(function(bridge) {
bridge.callHandler('callNativeCall', {'tel': '18942325686'}, function(response) {
alert('JSGetResponse:' + response)
})
})
总结:不管是Obj-C调用JS还是JS调用Obj-C 双方都可以选择是否传参,是否进行回调。
网友评论