iOS的WebView——WKWebView

前言

在iOS8中,苹果推出了WKWebViewWKWebView有一个突出特点,就是内存占用少。

但作为一个全新的WebView,API相比于之前的UIWebView肯定会有所不同。今天就在这里记录一下WKWebView的基本使用。

Webview的使用,通常包含以下几个部分:浏览器的基本设置,浏览器的各种回调,浏览器中js如何调用原生方法。

WKWebView基本使用

    self.webview = [[WKWebView alloc]init];
    [self.view addSubview:self.webview];
    [self.webview mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.view);
        make.right.equalTo(self.view);
        make.top.equalTo(self.view);
        make.bottom.equalTo(self.view);
    }];
    [_webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];

WKWebView与其他WebView的基本使用没有太大区别,将它当作一个普通的UIView进行布局,然后调用loadRequest方法,即可展示相应的网页。

WKWebView的设置

WKWebView的主要设置项都在configuration成员中(比如是否允许浏览器手指缩放,h5的浏览器能否自动播放等)这些都属于浏览器本身的设置项。

在此列举几项及其作用,由于类目繁多,会有遗漏,真正需要使用时,可以在xcode的help中寻找,查阅。

    // 默认值为NO,用户不可以放大或缩小页面;如果设置为YES,页面可以通过放大缩小去适应,用户也可以通过手势来放大和缩小
    [self.webview.configuration ignoresViewportScaleLimits];

    //这个值决定了网页内容的渲染是否在把内容全部加载到内存中再去处理。如果设置为YES,只有网页内容加载到内存里了才会去渲染
    [self.webview.configuration suppressesIncrementalRendering];
    // 默认使NO。这个值决定了用内嵌HTML5播放视频还是用本地的全屏控制。
    [self.webview.configuration allowsInlineMediaPlayback];
    // A Boolean value indicating whether AirPlay is allowed.
    [self.webview.configuration allowsAirPlayForMediaPlayback];
    // A Boolean value indicating whether HTML5 videos can play picture-in-picture.
    [self.webview.configuration allowsPictureInPictureMediaPlayback];
    // 网页中的多媒体是否需要手势才能开始播放(iOS 10) 可以设置仅音频需要、仅视频需要等四种状态
    self.webview.configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
    // 控制用户与webview进行选择交互时的粒度,可以选择整个块儿,或单个符号.
    self.webview.configuration.selectionGranularity = WKSelectionGranularityDynamic;

WKWebView的回调

WKWebView中包含了两个delegate。WKNavigationDelegateWKUIDelegate

WKNavigationDelegate

如命名,这个是WKWebView的导航的代理。它控制了WKWebView在加载一个页面流程中的各个关键时间节点的。相当于WKWebView加载的生命周期方法。

#pragma mark - WKNavigationDelegate
// 页面开始加载时调用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
    NSLog(@"页面开始加载");
}
// 当内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{
    NSLog(@"页面开始返回");
}
// 页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
    NSLog(@"页面完成加载");
}
// 页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation{
    NSLog(@"页面加载失败");
}
// 接收到服务器跳转请求之后调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{
    NSLog(@"页面重定向");
}
// 在收到响应后,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
    
    NSLog(@"%@",navigationResponse.response.URL.absoluteString);
    //允许跳转
    decisionHandler(WKNavigationResponsePolicyAllow);
    //不允许跳转
    //decisionHandler(WKNavigationResponsePolicyCancel);
}
// 在发送请求之前,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
    
    NSLog(@"%@",navigationAction.request.URL.absoluteString);
    //允许跳转
    decisionHandler(WKNavigationActionPolicyAllow);
    //不允许跳转
    //decisionHandler(WKNavigationActionPolicyCancel);
}

WKUIDelegate

WKUIDelegate控制了WKWebView的UI绘制。即我们可以掌管,部分H5中的绘制行为。

#pragma mark - WKUIDelegate
// 创建一个新的WebView
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures{
    return [[WKWebView alloc]init];
}
// 输入框
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler{
    completionHandler(@"http");
}
// 确认框
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler{
    completionHandler(YES);
}
// 警告框
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
    NSLog(@"%@",message);
    completionHandler();
}

js调用原生方法

拦截url

此方法的本质是,js会尝试加载某个URL,客户端在加载前拦截这个URL,通过解析这个URL识别它的内容,调用相应的原生方法,并阻上浏览器加载这个URL。

所以我们在decidePolicyForNavigationAction这个方法中进行拦截。

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
    
    NSLog(@"%@",navigationAction.request.URL.absoluteString);
    NSURL *url = navigationAction.request.URL;
    NSString *urlStr = url.absoluteString;
    
    if ([urlStr isEqualToString:@"xxx"]) {
        // do something ;
        
        //不允许跳转
        decisionHandler(WKNavigationActionPolicyCancel);
        return;
    }
    //允许跳转
    decisionHandler(WKNavigationActionPolicyAllow);
    
}

contentController

A WKUserContentController object provides a way for JavaScript to post messages and inject user scripts to a web view.

contentController苹果官方提供的js调用原生方法的类。它的使用方法是:

    ...
    self.contentController = self.webview.configuration.userContentController;
    [_contentController addScriptMessageHandler:self name:@"closeWebView"];
    ...

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
    if ([message.name isEqualToString:@"closeWebView"]) {
        //做处理 do something
        //message.body 为此 ScriptMessage 传递的消息内容
    }
}

js的调用方法:

window.webkit.messageHandlers.<事件名>.postMessage(需要传递的数据)

原生调用js方法

[self.webView evaluateJavaScript:@"function('action')" completionHandler:nil];

cookie的同步

WKWebview中,cookie默认不再自动处理,我们需要手动根据自己的需要,将cookie添加到请求中。如下是一个携带cookie的请求的演示:

    NSMutableDictionary *cookieDic = [NSMutableDictionary dictionary];
    NSMutableString *cookieValue = [NSMutableString stringWithFormat:@""];
    NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    for (NSHTTPCookie *cookie in [cookieJar cookies]) {
        [cookieDic setObject:cookie.value forKey:cookie.name];
    }
    // cookie重复,先放到字典进行去重,再进行拼接
    for (NSString *key in cookieDic) {
        NSString *appendString = [NSString stringWithFormat:@"%@=%@;", key, [cookieDic valueForKey:key]];
        [cookieValue appendString:appendString];
    }
    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.url]];
    [request addValue:cookieValue forHTTPHeaderField:@"Cookie"];
    [self.webview loadRequest:request];

以上,就介绍了** WKWebView**的基本应用,如有问题欢迎指正。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

扫码关注云+社区