由于写上篇博文的时候正在做手头项目,所以只是写了一半,这篇文章将会把剩下的内容进行完善。并且对上篇文章进行一个回顾。为了方便查看,新的博文已经把上一篇博文内容整理过来。
上篇博客我们说到了WKWebView和JS交互用到的几个协议方法。WKWebView把UIWebView重构成了14个类 3个协议
我们用到的是如下几个:
WKUserContentController: 提供使用 JavaScript post信息和注册 script的方法。
WKScriptMessage: 网页信息(共有四个属性,其中body属性就是用来接收js传的参数)。
WKWebViewConfiguration: webView配置控制器。
WKScriptMessageHandler:该协议下只有一个方法,就是我们用来进行交互需要用到的方法。
@param userContentController控制器调用用户的内容委托的方法。
@param消息脚本消息收到。
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;
先说下实现的效果,js端有两个按钮,点击按钮会使OC端按钮颜色变成蓝色并且执行方法输出结果,点击OC端按钮按,钮变成红色同时调用出js端alert同时实现传值(有的朋友会出现调用不出js的alert的问题,这个问题通过查找资料已经解决,在代码注释中写的很清晰)。
下面试JS代码和OC代码,相关叙述在代码注释中写的很清楚:
OC端代码:
#import "ViewController.h"
#import <WebKit/WebKit.h>
#import <JavaScriptCore/JavaScriptCore.h>
@interface ViewController ()<WKUIDelegate,WKScriptMessageHandler,WKNavigationDelegate>
{
WKWebView * _webView;
UIButton * _btn1;
UIButton * _btn2;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
/*
js调用OC
1.初始化配置控制器
2.WKUserContentController和配置控制器关联
3.注册H5中方法名,注意:此处必须和H5中方法名字一致。
4.初始化WebView
5.协议代理
*/
//进行配置控制器
WKWebViewConfiguration * con = [[WKWebViewConfigurationalloc]init];
WKUserContentController * user = [[WKUserContentControlleralloc]init];
con.userContentController = user;
//注册h5中方法名
[user addScriptMessageHandler:selfname:@"zdbApp"];
[user addScriptMessageHandler:selfname:@"getLatLng"];
_webView = [[WKWebViewalloc]initWithFrame:CGRectMake(0,20, self.view.bounds.size.width,self.view.bounds.size.height/3)configuration:con];
_webView.UIDelegate =self;
_webView.navigationDelegate =self;
NSString * path = [[NSBundlemainBundle] pathForResource:@"zhangdongbiao"ofType:@"html"];
NSURL * url = [[NSURLalloc]initFileURLWithPath:path];
NSURLRequest * request = [NSURLRequestrequestWithURL:url];
[_webViewloadRequest:request];
[self.viewaddSubview:_webView];
_btn1 = [[UIButtonalloc]initWithFrame:CGRectMake(100,self.view.bounds.size.height/3 + 100, 200,40)];
[_btn1setTitle:@"OC无参调用JS"forState:UIControlStateNormal];
_btn1.backgroundColor = [UIColorredColor];
[_btn1setTitleColor:[UIColorwhiteColor] forState:UIControlStateNormal];
_btn1.tag =10;
[_btn1addTarget:selfaction:@selector(btnClicke:)forControlEvents:UIControlEventTouchUpInside];
[self.viewaddSubview:_btn1];
_btn2 = [[UIButtonalloc]initWithFrame:CGRectMake(100,self.view.bounds.size.height/3 + 150, 200,40)];
[_btn2setTitle:@"OC调用JS(传参)"forState:UIControlStateNormal];
_btn2.backgroundColor = [UIColorredColor];
[_btn2setTitleColor:[UIColorwhiteColor] forState:UIControlStateNormal];
_btn2.tag =11;
[_btn2addTarget:selfaction:@selector(btnClicke:)forControlEvents:UIControlEventTouchUpInside];
[self.viewaddSubview:_btn2];
}
#pragma WKScriptMessageHandler 协议代理
-(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
if ([message.nameisEqualToString:@"zdbApp"]) {
NSLog(@"调用无参数");
_btn1.backgroundColor = [UIColorblueColor];
}elseif ([message.nameisEqualToString:@"getLatLng"]){
NSArray * arr = message.body;
NSLog(@"调用有参数 %@ %@",arr.firstObject,arr.lastObject);
_btn2.backgroundColor = [UIColorblueColor];
}
}
-(void)btnClicke:(UIButton *)btn{
switch (btn.tag) {
case10:
{
[_webViewevaluateJavaScript:@"OCCallJs1()"completionHandler:^(id_Nullable response, NSError * _Nullable error) {
//TODO
_btn1.backgroundColor = [UIColorredColor];
}];
}
break;
case11:
{
[_webViewevaluateJavaScript:@"OCCallJs2('Yasin','iOS')"completionHandler:^(id_Nullable response, NSError * _Nullable error) {
//TODO
_btn2.backgroundColor = [UIColorredColor];
}];
}
break;
default:
break;
}
}
//WKWebView 会拦截JS中的alert方法,需要自己重写 WKUIDelegate的runJavaScriptAlertPanelWithMessage方法,类似的还有Confirm,TextInput
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
UIAlertController *alertController = [UIAlertControlleralertControllerWithTitle:@"提示"message:message?:@""preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:([UIAlertActionactionWithTitle:@"确认"style:UIAlertActionStyleDefaulthandler:^(UIAlertAction *_Nonnull action) {
completionHandler();
}])];
[selfpresentViewController:alertControlleranimated:YEScompletion:nil];
}
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
UIAlertController *alertController = [UIAlertControlleralertControllerWithTitle:@"提示"message:message?:@""preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:([UIAlertActionactionWithTitle:@"取消"style:UIAlertActionStyleCancelhandler:^(UIAlertAction *_Nonnull action) {
completionHandler(NO);
}])];
[alertController addAction:([UIAlertActionactionWithTitle:@"确认"style:UIAlertActionStyleDefaulthandler:^(UIAlertAction *_Nonnull action) {
completionHandler(YES);
}])];
[selfpresentViewController:alertControlleranimated:YEScompletion:nil];
}
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
UIAlertController *alertController = [UIAlertControlleralertControllerWithTitle:promptmessage:@""preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField *_Nonnull textField) {
textField.text = defaultText;
}];
[alertController addAction:([UIAlertActionactionWithTitle:@"完成"style:UIAlertActionStyleDefaulthandler:^(UIAlertAction *_Nonnull action) {
completionHandler(alertController.textFields[0].text?:@"");
}])];
}
JS端代码:
<html>
<head>
<meta http-equiv="Content-Type"content="text/html; charset=UTF-8" />
<title>hello World</title>
</head>
<script type="text/javascript">
function JSCallOc1(){
window.webkit.messageHandlers.zdbApp.postMessage(null);
}
function JSCallOc2(){
window.webkit.messageHandlers.getLatLng.postMessage(['YasinZ','iOS']);
}
function OCCallJs1(){
alert("OC调用了无参数的js方法");
}
function OCCallJs2(name,num){
alert(name+num);
}
</script>
<body bgcolor="#555555">
<button type="button" onclick="JSCallOc1()">JS没有参数调用OC</button>
<button type="button" onclick="JSCallOc2()">JS有参数调用OC</button>
</body>
</html>