现在H5和原生的交互在日常开发中经常用的,很多APP为了优化APP,更加便捷灵活的更新页面,有很多页面交给了H5来开发,那么JS和原生的交互就很重要了。
现在常用的主要有两种方式:第三方WebViewJavascriptBridge和原生的交互
首先先来讲一下第一种WebViewJavascriptBridge
首先要引入WebViewJavascriptBridge,可以用cocoapods来引入
pod 'WebViewJavascriptBridge'
可以新建一个工具类然后引入
#import <WebViewJavascriptBridge.h>
@property (nonatomic, strong) WebViewJavascriptBridge *bridge;
@property(nonatomic,strong)WKWebView * webView;
然后和webview建立关系
- (void)configureWithWebView:(WKWebView *)webView {
self.webView = webView;
// 3.开启日志
[WebViewJavascriptBridge enableLogging];
// 4.给webView建立JS和OC的沟通桥梁
self.bridge = [WebViewJavascriptBridge bridgeForWebView:self.webView];
[self.bridge setWebViewDelegate:self];
}
这里是JS调用OC的API:访问相册
-(void)openCamera{
/* JS调用OC的API:访问相册 */
// self.Controller = [self getCurrentViewController];
[self.bridge registerHandler:@"openCamera" handler:^(id data, WVJBResponseCallback responseCallback) {
NSLog(@"需要%@图片", data[@"count"]);
// UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera;
// if ([UIImagePickerController isSourceTypeAvailable:(UIImagePickerControllerSourceTypeCamera)]) {
UIImagePickerController * picker =[[UIImagePickerController alloc] init];
picker.delegate = self;
//设置拍照后的图片可被编辑
picker.allowsEditing = YES;
// picker.sourceType = sourceType;
self.Controller = [self getCurrentViewController];
// [self presentModalViewController:picker animated:YES];被废弃的
[self.Controller presentViewController:picker animated:YES completion:nil];
// }
}];
/* JS调用OC的API:访问底部弹窗 */
[self.bridge registerHandler:@"showSheet" handler:^(id data, WVJBResponseCallback responseCallback) {
UIAlertController *vc = [UIAlertController alertControllerWithTitle:@"你猜我出不出来?" message:@"嘻嘻嘻嘻!!" preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil];
[vc addAction:cancelAction];
[vc addAction:okAction];
[[self getCurrentViewController] presentViewController:vc animated:YES completion:nil];
}];
}
在Controller页面创建一个webview
self.webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 300, self.view.frame.size.width, 300)];
[self.view addSubview:self.webView];
self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 600, 100, 100)];
[self.view addSubview:self.imageView];
NSString *indexPath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
NSString *appHtml = [NSString stringWithContentsOfFile:indexPath encoding:NSUTF8StringEncoding error:nil];
NSURL *baseUrl = [NSURL fileURLWithPath:indexPath];
[self.webView loadHTMLString:appHtml baseURL:baseUrl];
[[HLWebTool HLWebToolAPI] configureWithWebView:self.webView];
[[HLWebTool HLWebToolAPI] openCamera];//这个方法要调用的
index中的代码
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0">
<style>
body{
background-color:paleturquoise;
}
button{
border:0;
width: 150px;
height: 35px;
background-color: orangered;
color: white;
font-size: 16px;
border-radius: 6px;
}
</style>
</head>
<body>
<h2>JS调用OC中的方法</h2>
<button id="btn">访问OC相册</button>
<button id="btn1">调用OC提示窗</button>
<p></p>
</body>
<script>
// 这段代码是固定的,必须要放到js中
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和JS之间相互调用
setupWebViewJavascriptBridge(function(bridge) {
/* JS给OC提供公开的API, 在OC中可以手动调用此API, 并且可以接收OC中传过来的参数,同时可回调OC */
// 获取用户信息
bridge.registerHandler('getUserInfo', function(data, responseCallback) {
console.log("OC中传递过来的参数:", data);
// 把处理好的结果返回给OC
responseCallback({"userID":"DX001", "userName":"旋之华", "age":"18", "otherName":"旋之华"})
});
// 弹框输出
bridge.registerHandler('alertMessage', function(data, responseCallback) {
alert(data);
console.log(data);
});
// 动态跳转到京东商城
bridge.registerHandler('pushToNewWebSite', function(data, responseCallback) {
window.location.href = data.url;
});
bridge.registerHandler('insertImgToWebPage', function(data, responseCallback) {
var img = document.createElement('img');
img.src = data.url;
img.width = 200;
document.body.appendChild(img);
});
/* OC给JS提供公开的API, 在JS中可以手动调用此API, 并且可以接收OC中传过来的参数,同时可回调OC */
// 调用OC中的打开相册方法
document.getElementById('btn').onclick = function () {
bridge.callHandler('openCamera', {'count':'10张'}, function responseCallback(responseData) {
console.log("OC中返回的参数:", responseData)
});
};
document.getElementById('btn1').onclick = function () {
bridge.callHandler('showSheet', '', function responseCallback(responseData) {
console.log("OC中返回的参数:", responseData)
});
};
})
</script>
</html>
以上是JS调用OC的方法,接下来讲OC调用JS
Controller里面添加点击方法
UIButton * userBut = [[UIButton alloc] initWithFrame:CGRectMake(0, 50, 100, 50)];
[self.view addSubview:userBut];
[userBut setTitle:@"获取用户信息" forState:(UIControlStateNormal)];
[userBut addTarget:self action:@selector(getUserinfo) forControlEvents:(UIControlEventTouchUpInside)];
///* 获取用户信息 */
- (void)getUserinfo {
// 调用JS中的API
[[HLWebTool HLWebToolAPI] getUserinfo];
}
工具类中实现方法
- (void)getUserinfo {
// 调用JS中的API
[self.bridge callHandler:@"getUserInfo" data:@{@"userId":@"DX001"} responseCallback:^(id responseData) {
NSString *userInfo = [NSString stringWithFormat:@"%@,姓名:%@,年龄:%@", responseData[@"userID"], responseData[@"userName"], responseData[@"age"]];
UIAlertController *vc = [UIAlertController alertControllerWithTitle:@"从网页端获取的用户信息" message:userInfo preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil];
[vc addAction:cancelAction];
[vc addAction:okAction];
[[self getCurrentViewController] presentViewController:vc animated:YES completion:nil];
}];
}