iOS WKWebView

WKWebView是iOS8之后推出来的控件,目的是为了取代UIWebViewWKWebView相比UIWebView有这些优点:

  • 1、支持更多的html5特性
  • 2、支持高达60fps的滚动刷新率以及内置手势
  • 3、与safari相同的javascript引擎
  • 4、不会占用更多的内存

下面来讲讲它的使用

一、创建

创建配置
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
WKUserContentController* userContent = [[WKUserContentController alloc] init];
        // 添加消息处理,注意:self指代的对象需要遵守WKScriptMessageHandler协议,结束时需要移除
        //这个类似uiwebview于js交互里的JSContext创建js对象。例如context["log"] = self;
        //但是js通过log发起调用时是不一样的
        
        [userContent addUserScript:wkUScript];
        [userContent addScriptMessageHandler:self name:@"log"];
//这里的scriptMessageHandler代理一定要实现
        
        // 将UserConttentController设置到配置文件
        config.userContentController = userContent;

WKWebView *_wkWebview = [[WKWebView alloc]initWithFrame:self.view.frame configuration:config];
        _wkWebview.UIDelegate = self;
        _wkWebview.navigationDelegate = self;
        _wkWebview.allowsBackForwardNavigationGestures = YES;//支持手势返回

二、各种代理

//通过js调用原生方法触发的方法
//例如:js里执行这段函数window.webkit.messageHandlers.log.postMessage({'abc':'def'})就可以调起WKScriptMessageHandler的协议方法
#pragma mark-- WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    
    NSLog(@"message name is %@",message.name);//表示web在js里注册的对象名字
    NSLog(@"message body is %@",message.body);//h5传递的数据
    NSLog(@"message frameInfo is %@",message.frameInfo);
    
}


#pragma mark-- WKUIDelegate

- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
    
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
    
    [alertController addAction:([UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler();
        NSLog(@"点击了取消按钮==%@",message);
    }])];
    
    [alertController addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler();
        NSLog(@"点击了确定按钮==%@",message);
    }])];
    
    [self presentViewController:alertController animated:YES completion:^{
        NSLog(@"alert show");
    }];
    
}

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

- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable result))completionHandler {
    
    NSLog(@"%s",__FUNCTION__);
    completionHandler(defaultText);
    
    //input控件里的内容回调
    
}


- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {
    NSLog(@"%s",__FUNCTION__);
    WKFrameInfo *frameInfo = navigationAction.targetFrame;
    if (![frameInfo isMainFrame]) {
        [webView loadRequest:navigationAction.request];
    }
    return nil;
    
}



#pragma mark-- WKNavigationDelegate

- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation {
    
    NSLog(@"%s",__FUNCTION__);
    
}

- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation {
    
    NSLog(@"%s",__FUNCTION__);
    
}

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
    
    NSLog(@"%s",__FUNCTION__);
    
    [self.wkWebview evaluateJavaScript:@"document.title" completionHandler:^(id _Nullable item, NSError * _Nullable error) {
        NSLog(@"item is %@ error is %@",item,error);
        //item的值是执行javaScript的返回值.如果error有值就表示执行javaScript出错了
    }];
    
    
    NSHTTPCookie *cookie;
    NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    for (cookie in [cookieJar cookies]) {
        NSLog(@"cookie is %@", cookie);
    }
    
}

- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
    
    NSLog(@"%s",__FUNCTION__);
    NSLog(@"error is %@",error);
    
}

- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
    
    NSLog(@"%s",__FUNCTION__);
    
    [webView.configuration.userContentController removeScriptMessageHandlerForName:@"log"];
    NSLog(@"error is %@",error);
    
}

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    
    NSLog(@"%s",__FUNCTION__);
    
    //在发送请求之前,决定是否跳转
    //处理打电话的功能
    NSURL *URL = navigationAction.request.URL;
    NSLog(@"获取到URL========%@",URL);
    NSString *scheme = [URL scheme];
    UIApplication *app = [UIApplication sharedApplication];
    // 打电话
    if ([scheme isEqualToString:@"tel"]) {
        if ([app canOpenURL:URL]) {
            [app openURL:URL];
            // 一定要加上这句,否则会打开新页面
            decisionHandler(WKNavigationActionPolicyCancel);
            
            return;
        }
    }
    
    NSLog(@"headers is %@ %d",navigationAction.request.allHTTPHeaderFields,navigationAction.request.HTTPShouldHandleCookies);
    
    decisionHandler(WKNavigationActionPolicyAllow);
    
}

- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
    NSLog(@"%s",__FUNCTION__);
    //接收到服务器响应之后决定是否跳转
    decisionHandler(WKNavigationResponsePolicyAllow);
    
}
//https权限认证
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        if ([challenge previousFailureCount] == 0) {
            NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
            completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
        } else {
            completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
        }
    } else {
        completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
    }
    NSLog(@"%s",__FUNCTION__);
}

三、wkwebview调用

NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];
    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
    [_wkWebview loadRequest:urlRequest];

四、JS调用Native

//必须使用设置的代理进行调动,比如我们设置了log
window.webkit.messageHandlers.log.postMessage('h5给native发送一条消息');

五、Native调用JS

两种方式:
//第一种,web执行js代码,下面是获取网页tittle的示例
[self.wkWebview evaluateJavaScript:@"document.title" completionHandler:^(id _Nullable item, NSError * _Nullable error) {
        NSLog(@"item is %@ error is %@",item,error);
        //item的值是执行javaScript的返回值.如果error有值就表示执行javaScript出错了
    }];
//第二种,通过WKUserScript执行js代码
[self.wkWebview.configuration.userContentController addUserScript:[[WKUserScript alloc]initWithSource:@"alert('wk弹框')" injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES] ];
/* WKUserScriptInjectionTimeAtDocumentEnd表示document结构渲染完成之后,子目录完成之前
forMainFrameOnly表示YES只在主窗口渲染,NO是在全局窗口渲染
*/

更新时间: 2018-09-18

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值