!!本文严重参考:http://www.cnblogs.com/L-vincen/p/6681435.html
WebViewJavascriptBridge git地址:https://github.com/marcuswestin/WebViewJavascriptBridge
导入
pod 'WebViewJavascriptBridge', '~> 5.0
JS 调用 原生 方法
贴一下 demo.html 的 JS 段落 ,看注释,主要知道JS 怎么调用 原生方法 和 注册JS方法 供JS调用
<script type="text/javascript">
//这是必须要写的,用来初始化一些设置
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)
}
//这也是固定的, OC 调JS , 需要给OC调用的函数必须写在这个函数里面
setupWebViewJavascriptBridge(function(bridge) {
bridge.registerHandler('testJSFunction', function(data, responseCallback) {
alert('JS方法被调用:'+data);
responseCallback('js执行过了');
})
})
//这个 shareClick 就是 原生那边 注入的函数 , 通过这个方法来调用原生 和传值
//parmas 是JS 给OC的数据 , response 是 OC函数被调用之后 再 告诉JS 我被调用了
//比如微信分享,给Dic给原生 , 原生分享成功后再把结果回调给JS 进行处理
function shareClick() {
var params = {'title':'测试分享的标题','content':'测试分享的内容','url':'http://www.baidu.com'};
WebViewJavascriptBridge.callHandler('shareClick',params,function(response) {
alert(response);
});
}
</script>
原生代码
#import "WKWebViewJavascriptBridge.h" //注意是 WK 开头的 , 如果不需要适配8.0以下的可以直接就用WKWebview
@property (nonatomic, strong) WKWebView *webView;
@property WKWebViewJavascriptBridge* bridge;
初始化
self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://192.168.0.114:8020/AppTest/index.html"]]];
self.webView.UIDelegate = self;
self.bridge = [WKWebViewJavascriptBridge bridgeForWebView:self.webView];
[_bridge setWebViewDelegate:self];
[self.view addSubview:self.webView];
//注册原生方法给JS调用
- (void)registShareFunction {
[_webViewBridge registerHandler:@"shareClick" handler:^(id data, WVJBResponseCallback responseCallback) {
// data 的类型与 JS中传的参数有关
NSDictionary *tempDic = data;
// 在这里执行分享的操作
NSString *title = [tempDic objectForKey:@"title"];
NSString *content = [tempDic objectForKey:@"content"];
NSString *url = [tempDic objectForKey:@"url"];
// 将分享的结果返回到JS中
NSString *result = [NSString stringWithFormat:@"分享成功:%@,%@,%@",title,content,url];
responseCallback(result); //回调给JS
}];
}
//原生调用JS , JS 中先声明testJSFunction 函数
- (void)tt_hander {
//testJSFunction 是JS的方法
[_webViewBridge callHandler:@"testJSFunction" data:@"一个字符串" responseCallback:^(id responseData) {
NSLog(@"调用完JS后的回调:%@",responseData)
}];
}
//拦截alert方法
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(nonnull NSString *)message initiatedByFrame:(nonnull WKFrameInfo *)frame completionHandler:(nonnull void (^)(void))completionHandler {
NSLog(@"%@", message);
completionHandler();
}
遇到一个坑:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Completion handler passed to -[WKWebViewJavascriptBridge webView:decidePolicyForNavigationAction:decisionHandler:] was called more than once'
解决方法:
if ([_base isCorrectProcotocolScheme:url]) {
// ...
decisionHandler(WKNavigationActionPolicyCancel);
} else if (strongDelegate && ... ) {
[_webViewDelegate webView:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];
} else {
decisionHandler(WKNavigationActionPolicyAllow);
}
是的,就多加一个else就可以了!!!