个人demo地址:https://github.com/XGPASS/XGDevelopDemo
WebViewJavascriptBridge地址:https://github.com/marcuswestin/WebViewJavascriptBridge
iOS端代码:参考链接:http://www.jianshu.com/p/e951af9e5e74
//
// WKWebViewBridgeController.m
// XGDevelopDemo
//
// Created by 小广 on 2016/11/4.
// Copyright © 2016年 小广. All rights reserved.
// WebViewJavascriptBridge 第三方使用WKWebView
// WebViewJavascriptBridge地址 https://github.com/marcuswestin/WebViewJavascriptBridge
// WebViewJavascriptBridge iOS使用地址 http://www.jianshu.com/p/e951af9e5e74
// WebViewJavascriptBridge Java使用地址 http://blog.csdn.net/sk719887916/article/details/47189607
#import "WKWebViewBridgeController.h"
#import "WKWebViewJavascriptBridge.h"
#import <WebKit/WebKit.h>
@interface WKWebViewBridgeController ()<WKNavigationDelegate, WKUIDelegate>
@property WKWebViewJavascriptBridge* bridge;
@property (nonatomic, strong) WKWebView *wkWebView; // webview
@end
@implementation WKWebViewBridgeController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
[self setUpWKWebView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// viewWillAppear和viewWillDisappear对setWebViewDelegate处理,不处理会导致内存泄漏
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (self.bridge) {
[self.bridge setWebViewDelegate:self];
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.bridge setWebViewDelegate:nil];
}
- (void)dealloc
{
NSLog(@"dealloc==dealloc==");
}
- (void)setUpWKWebView {
self.wkWebView = [[WKWebView alloc] initWithFrame:self.view.bounds];
self.wkWebView.navigationDelegate = self;
self.wkWebView.UIDelegate = self;
[self.view addSubview:self.wkWebView];
[WKWebViewJavascriptBridge enableLogging];
_bridge = [WKWebViewJavascriptBridge bridgeForWebView:self.wkWebView];
[_bridge setWebViewDelegate:self];
// 注册一下
__weak __typeof(self)weakSelf = self;
// js调用oc
[_bridge registerHandler:@"_app_setTitle" handler:^(id data, WVJBResponseCallback responseCallback) {
responseCallback(@"this is callback data to JS");
if ([data isKindOfClass:[NSString class]]) {
weakSelf.title = (NSString *)data;
return ;
}
if (data) {
weakSelf.title = [NSString stringWithFormat:@"%@",data];
}
}];
// oc调用js
// [_bridge callHandler:@"getCodeScan" data:@"oc调用js端方法" responseCallback:^(id responseData) {
// //
// NSLog(@"responseData===%@==",responseData);
// }];
[self loadExamplePage:self.wkWebView];
}
// 加载h5
- (void)loadExamplePage:(WKWebView*)webView {
NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"xg_test" ofType:@"html"];
NSString* appHtml = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil];
NSURL *baseURL = [NSURL fileURLWithPath:htmlPath];
[webView loadHTMLString:appHtml baseURL:baseURL];
}
// 页面开始加载时调用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
self.title = NSLocalizedString(@"Loading...", @"");
}
// 处理拨打电话
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURL *URL = navigationAction.request.URL;
NSString *scheme = [URL scheme];
if ([scheme isEqualToString:@"tel"]) {
NSString *resourceSpecifier = [URL resourceSpecifier];
// 这种拨打电话的写法,真机可显示效果,模拟器不显示
NSString *callPhone = [NSString stringWithFormat:@"telprompt://%@", resourceSpecifier];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:callPhone]];
}
decisionHandler(WKNavigationActionPolicyAllow);
}
/// alert的处理
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提醒" message:message preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
completionHandler();
}]];
[self presentViewController:alert animated:YES completion:nil];
}
@end
Java端代码参考:http://blog.csdn.net/sk719887916/article/details/47189607
html里的代码:github上只找到oc的,链接:https://github.com/marcuswestin/WebViewJavascriptBridge/blob/master/Example%20Apps/ExampleApp.html
下面的html上综合oc里js和Java里js,已经验证,都可以调用,若有更好的写法,请大家指出,共同进步。谢谢。
个人demo里有例子,地址:https://github.com/XGPASS/XGDevelopDemo
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>测试</title>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta name="description" content="">
<meta name="keywords" content="">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="format-detection" content="telephone=no" />
<meta name="format-detection" content="email=no" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0" />
<script src="js/jquery.min.js"></script>
<script>
// 固定写法 函数名字可变
function setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
} else {
document.addEventListener('WebViewJavascriptBridgeReady' , function() {
callback(WebViewJavascriptBridge)
}, false );
}
// =====以下是iOS必须的特殊处理========
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);
// =====以上是iOS必须的特殊处理========
}
// 固定写法2 函数名字与1保持一致
setupWebViewJavascriptBridge(function(bridge) {
// Java 注册回调函数,第一次连接时调用 初始化函数
bridge.init();
});
// 每个方法的特殊处理
function setTitle() {
WebViewJavascriptBridge.callHandler('_app_setTitle',
'这是一个nav标题',
function (response) {
// 移动端回传的数据
alert('移动端回传的数据:' + response);
});
}
</script>
<style>
html {
font-family: Helvetica;
color: #222;
}
h1 {
color: steelblue;
font-size: 24px;
margin-top: 24px;
}
button {
margin: 0 3px 10px;
font-size: 12px;
}
.logLine {
border-bottom: 1px solid #ccc;
padding: 4px 2px;
font-family: courier;
font-size: 11px;
}
input {
height: 32px;
margin: 30px;
}
</style>
</head>
<body>
<div id='buttons'></div>
<div id='log'></div>
<div class="pointexchange">
<div>
<img src="points4.png" width="47px" height="47px" title="points4.png" /><br />
<label>积分兑换实物</label>
</div>
<div>
<img src="points1.png" width="47px" height="47px" title="points1.png" /><br />
<label>积分兑换红包</label>
</div>
<div>
<img src="points2.png" width="47px" height="47px" title="points2.png" /><br />
<label>积分参与活动</label>
</div>
</div>
<br />
<input id="test" type="button" οnclick="setTitle()" value="设置标题" />
<br />
<br />
<a href="tel:13112345678">移动WEB页面JS一键拨打号码咨询功能</a>
<br />
</body>
</html>