iOS|iOS WKWebView

WKWebView是iOS8之后推出来的控件,目的是为了取代UIWebView
WKWebView相比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是在全局窗口渲染 */

【iOS|iOS WKWebView】更新时间: 2018-09-18

    推荐阅读