WKWebView 与 JS 交互简单使用

通过调研,我决定使用WKWebView替换原来的UIWebView。
遇到的第一个问题就是WKWebView无法在我喜爱的xib上设置,通过搜索资料,原来WKWebView没有实现initWithCoder方法,自然也就找到了解决办法:

自定义一个MyWebView,继承自WKWebView

.h

#import 
@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,并且设置协议与协议方法
    [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视图释放");
}

你可能感兴趣的:(iOS,iphone)