美文网首页
WKWebView 与 JS 交互简单使用

WKWebView 与 JS 交互简单使用

作者: biyuhuaping | 来源:发表于2018-08-16 14:26 被阅读55次

    通过调研,我决定使用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视图释放");
    }
    
    

    相关文章

      网友评论

          本文标题:WKWebView 与 JS 交互简单使用

          本文链接:https://www.haomeiwen.com/subject/qsanbftx.html