您的位置:首页 > 移动开发

WKWebView 与JS的交互

2016-12-07 11:48 309 查看

 WKWebView 是iOS 8引入的WebKit框架中的内容,旨在替换之前的UIWebView,WKWebView相比UIWebView加载速度更快,优化内存,可以更好地与JS交互.


使用WKWebView需遵守实现三个协议(<WKScriptMessageHandler,WKNavigationDelegate,WKUIDelegate>)

初始化WKWebView时需要配置其WKWebViewConfiguration属性,如下:

WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];

// 设置偏好设置
config.preferences = [[WKPreferences alloc] init];
// 默认为0
config.preferences.minimumFontSize = 10;
// 默认认为YES
config.preferences.javaScriptEnabled = YES;
// 在iOS上默认为NO,表示不能自动通过窗口打开
config.preferences.javaScriptCanOpenWindowsAutomatically = NO;
// web内容处理池
config.processPool = [[WKProcessPool alloc] init];
// 通过JS与webview内容交互
config.userContentController = [[WKUserContentController alloc] init];
// "xxx"为注入JS对象名称,需与JS代码一致
[config.userContentController addScriptMessageHandler:self name:@"xxx"];

self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds
configuration:config];
NSURL *path = [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"html"];
[self.webView loadRequest:[NSURLRequest requestWithURL:path]];
[self.view addSubview:self.webView];
其中WKNavigationDelegate部分协议方法有
#pragma mark - WKNavigationDelegate
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSString *hostname = navigationAction.request.URL.host.lowercaseString;
if (navigationAction.navigationType == WKNavigationTypeLinkActivated
&& ![hostname containsString:@".baidu.com"]) {
//对于跨域,需要手动跳转
[[UIApplication sharedApplication] openURL:navigationAction.request.URL];
// 不允许web内跳转
decisionHandler(WKNavigationActionPolicyCancel);
} else {
self.progressView.alpha = 1.0;
decisionHandler(WKNavigationActionPolicyAllow);
}
NSLog(@"%s", __FUNCTION__);
}

- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
decisionHandler(WKNavigationResponsePolicyAllow);
NSLog(@"%s", __FUNCTION__);
}
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *__nullable credential))completionHandler {
NSLog(@"%s", __FUNCTION__);
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
}

- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
NSLog(@"%s", __FUNCTION__);
}


 WKUIDelegate部分方法有

//JS代码里有提醒框

- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo
*)frame completionHandler:(void (^)(void))completionHandler;

//JS代码里有确定按钮

- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo
*)frame completionHandler:(void (^)(BOOL result))completionHandler;

//JS代码里有输入框

- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullableNSString
*)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *__nullable
result))completionHandler;

代码示例:
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
NSLog(@"%s", __FUNCTION__);
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"alert" message:@"JS调用alert" preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {    //执行交互   completionHandler();
}]];
[self presentViewController:alert animated:YES completion:NULL];
NSLog(@"%@", message);
}

- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler {
NSLog(@"%s", __FUNCTION__);

UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"confirm" message:@"JS调用confirm" preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//执行交互
completionHandler(YES);
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
completionHandler(NO);
}]];
[self presentViewController:alert animated:YES completion:NULL];

NSLog(@"%@", message);
}
//IOS与JS的交互
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler {
NSLog(@"%s", __FUNCTION__);

NSLog(@"%@", prompt);
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"textinput" message:@"JS调用输入框" preferredStyle:UIAlertControllerStyleAlert];
[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.textColor = [UIColor redColor];
}];

[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//执行交互
completionHandler([[alert.textFields lastObject] text]);
}]];

[self presentViewController:alert animated:YES completion:NULL];
}

执行完这些方法,如果是JS向IOS端传值的话会调用WKScriptMessageHandler的

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage
*)message;

这里注意要和之前配置的config中的userContentController的"xxx"name一致.示例代码如下
- (void)userContentController:(WKUserContentController *)userContentController
didReceiveScriptMessage:(WKScriptMessage *)message {
if ([message.name isEqualToString:@"xxx"]) {
NSLog(@"&&&&&%@", message.body);
}else{
NSLog(@"---===%@", message.name);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: