陈斌彬的技术博客

Stay foolish,stay hungry

WKWebView 的使用

##WKWebView 的使用简介

WKWebView相对于UIWebView强大了很多,内存的消耗相对少了,所提供的接口也丰富了。

现在谈一谈WKWebView的基本使用

1. navigationDelegate

- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { // 类似UIWebView的 -webViewDidStartLoad:  
    NSLog(@"didStartProvisionalNavigation");  
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;  
}  

- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {  
    NSLog(@"didCommitNavigation");  
}  

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { // 类似 UIWebView 的 -webViewDidFinishLoad:  
    NSLog(@"didFinishNavigation");  
    [self resetControl];  
    if (webView.title.length > 0) {  
        self.title = webView.title;  
    }  

}  
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {  
    // 类似 UIWebView 的- webView:didFailLoadWithError:  

    NSLog(@"didFailProvisionalNavigation");  

}  
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {  

    decisionHandler(WKNavigationResponsePolicyAllow);  
}  


- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {  
    // 类似 UIWebView 的 -webView: shouldStartLoadWithRequest: navigationType:  

    NSLog(@"4.%@",navigationAction.request);  


    NSString *url = [navigationAction.request.URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];  



    decisionHandler(WKNavigationActionPolicyAllow);  

}  
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler {  

}  

2 UIDelegate

- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {  
    // 接口的作用是打开新窗口委托  
    [self createNewWebViewWithURL:webView.URL.absoluteString config:configuration];  

    return currentSubView.webView;  
}  

- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(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)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *))completionHandler {  

    completionHandler(@"Client Not handler");  

}  

3. WKWebView 执行脚本方法

- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^)(id, NSError *))completionHandler;  

completionHandler 拥有两个参数,一个是返回错误,一个可以返回执行脚本后的返回值

4. WKWebView 的Cookie问题

UIWebView 中会自动保存Cookie,如果登录了一次,下次再次进入的时候,会记住登录状态

而在WKWebView中,并不会这样,WKWebView在初始化的时候有一个方法

- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration  
通过这个方法,设置 configuration 让WKWebView知道登录状态,configuration 可以通过已有的Cookie进行设置,也可以通过保存上一次的configuration进行设置
参考 stackoverflow上回答:http://stackoverflow.com/questions/26573137/can-i-set-the-cookies-to-be-used-by-a-wkwebview/26577303#26577303

WKWebView * webView = /*set up your webView*/  
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/index.html"]];  
[request addValue:@"TeskCookieKey1=TeskCookieValue1;TeskCookieKey2=TeskCookieValue2;" forHTTPHeaderField:@"Cookie"];  
// use stringWithFormat: in the above line to inject your values programmatically  
[webView loadRequest:request];  


WKUserContentController* userContentController = WKUserContentController.new;  
WKUserScript * cookieScript = [[WKUserScript alloc]   
    initWithSource: @"document.cookie = 'TeskCookieKey1=TeskCookieValue1';document.cookie = 'TeskCookieKey2=TeskCookieValue2';"  
    injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];  
// again, use stringWithFormat: in the above line to inject your values programmatically  
[userContentController addUserScript:cookieScript];  
WKWebViewConfiguration* webViewConfig = WKWebViewConfiguration.new;  
webViewConfig.userContentController = userContentController;  
WKWebView * webView = [[WKWebView alloc] initWithFrame:CGRectMake(/*set your values*/) configuration:webViewConfig];