WKWebView 与 JS 交互简单使用
2018-08-16 本文已影响55人
biyuhuaping
通过调研,我决定使用WKWebView替换原来的UIWebView。
遇到的第一个问题就是WKWebView无法在我喜爱的xib上设置,通过翻墙搜索资料,原来WKWebView没有实现initWithCoder方法,自然也就找到了解决办法:
自定义一个MyWebView,继承自WKWebView
.h
#import <WebKit/WebKit.h>
@interface MyWebView : WKWebView
@end
.m
#import "MyWebView.h"
@implementation MyWebView
- (instancetype)initWithCoder:(NSCoder *)coder
{
CGRect frame = [[UIScreen mainScreen] bounds];
WKWebViewConfiguration *configuration = [WKWebViewConfiguration new];
configuration.userContentController = [WKUserContentController new];
WKPreferences *preferences = [WKPreferences new];
preferences.javaScriptCanOpenWindowsAutomatically = YES;
configuration.preferences = preferences;
self = [super initWithFrame:frame configuration:configuration];
self.translatesAutoresizingMaskIntoConstraints = NO;
return self;
}
@end
这样就可以像UIWebView一样在xib设置约束了。
导入MyWebView,投入使用
#import "WebViewController.h"
#import "MyWebView.h"
//1. 代理
@interface WebViewController ()<WKScriptMessageHandler, WKUIDelegate>
@property (strong, nonatomic) IBOutlet MyWebView *webView;
@end
@implementation WebViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem *button = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"返回"] style:UIBarButtonItemStylePlain target:self action:@selector(goBack)];
self.navigationItem.leftBarButtonItem = button;
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.urlString]]];
self.webView.UIDelegate = self;
//JS调用OC:设置addScriptMessageHandler与name,并且设置<WKScriptMessageHandler>协议与协议方法
[self.webView.configuration.userContentController addScriptMessageHandler:self name:@"callNativeKaihu"];//开户
}
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
// 移除handlers,防止内存泄露
[self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"callNativeKaihu"];
}
- (void)goBack{
if ([self.webView canGoBack]) {
[self.webView goBack];
}else{
[self.navigationController popViewControllerAnimated:YES];
}
}
#pragma mark - WKScriptMessageHandler
//OC在JS调用方法做的处理
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
// 打印所传过来的参数,只支持NSNumber, NSString, NSDate, NSArray, NSDictionary, NSNull类型
NSLog(@"JS调用了 %@ 方法,返回参数 %@",message.name, message.body);
if ([message.name isEqualToString:@"callNativeKaihu"]) {
DRElectronicAccountVC *vc = [[DRElectronicAccountVC alloc]initWithNibName:@"DRElectronicAccountVC" bundle:nil];
vc.dictionary = dic[@"data"];
[self.navigationController pushViewController:vc animated:YES];
}
}
WKWebView默认禁止了一些跳转
- UIWebView
打开www.apple.com/itunes/跳转到appStore, 拨打电话, 唤起邮箱等一系列操作UIWebView默认支持的。 - WKWebView
默认禁止了以上行为,除此之外,js端通过alert(),弹窗的动作也被禁掉了。
如何支持呢?
首先要设置WKWebView的WKUIDelegate,并实现以下方法
#pragma mark - WKUIDelegate
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
// js 里面的alert实现,如果不实现,网页的alert函数无效
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
completionHandler();
}]];
[self presentViewController:alertController animated:YES completion:^{}];
}
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler {
// js 里面的alert实现,如果不实现,网页的alert函数无效
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
completionHandler(YES);
}]];
[alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
completionHandler(NO);
}]];
[self presentViewController:alertController animated:YES completion:^{}];
}
- (void)dealloc{
NSLog(@"观测web视图释放");
}