WKWebView的使用和各种坑的解决方法(OC+Swift)

来源:互联网 发布:java stack overflow 编辑:程序博客网 时间:2024/06/03 13:25

WKWebView的基本介绍和使用

WKWebView的几个代理方法

WKWebView是苹果在iOS 8中引入的新组件,目的是给出一个新的高性能的WebView解决方案,摆脱过去 UIWebView的老、旧、笨重,特别是内存占用量巨大的问题,它使用Nitro JavaScript引擎,这意味着所有第三方浏览器运行JavaScript将会跟safari一样快。

看到我这篇文章的小伙伴,对iOS的开发应该有一定的了解,肯定用过UIWebView,现在就用UIWebViewWKWebView的代理方法做一个对比。

  • 加载状态的回调(用来跟踪页面加载的过程(页面开始加载、加载完成、加载失败的方法),还可以决定是否跳转):

    1. 准备加载页面
        UIWebViewDelegate: - webView:shouldStartLoadWithRequest:navigationType        WKNavigationDelegate: - webView:didStartProvisionalNavigation:
2. **内容开始加载**`(view的过渡动画可在此方法中加载)`
        UIWebViewDelegate: - webViewDidStartLoad:        WKNavigationDelegate: - webView:didCommitNavigation:
3. **页面加载完成**`(view的过渡动画的移除可在此方法中进行)`
        UIWebViewDelegate: - webViewDidFinishLoad:        WKNavigationDelegate: - webView:didFinishNavigation:
4. **页面加载失败**
        UIWebViewDelegate: - webView:didFailLoadWithError:        WKNavigationDelegate: - webView:didFailNavigation:withError:        WKNavigationDelegate: - webView:didFailProvisionalNavigation:withError:

此外,WKWebKit还有三个页面跳转的代理方法:

  • 页面跳转的代理
    1. 接收到服务器跳转请求的代理
        WKNavigationDelegate: - webView:didReceiveServerRedirectForProvisionalNavigation:
2. **在收到响应后,决定是否跳转的代理**
        WKNavigationDelegate: - webView:decidePolicyForNavigationResponse:decisionHandler:
3. **在发送请求之前,决定是否跳转的代理**
        WKNavigationDelegate: - webView:decidePolicyForNavigationAction:decisionHandler:

WKWebView增加的属性

  1. WKWebViewConfiguration *configuration:初始化WKWebView的时候的配置,后面会用到
  2. WKBackForwardList *backForwardList:相当于访问历史的一个列表
  3. double estimatedProgress:进度,有这个之后就不用自己写假的进度条了

WKWebView的使用

OC代码:

    // 创建WKWebView    WKWebView *webView = [[WKWebView alloc] initWithFrame:[UIScreen mainScreen].bounds];    // 设置访问的URL    NSURL *url = [NSURL URLWithString:@"http://www.jianshu.com"];    // 根据URL创建请求    NSURLRequest *request = [NSURLRequest requestWithURL:url];    // WKWebView加载请求    [webView loadRequest:request];    // 将WKWebView添加到视图    [self.view addSubview:webView];

Swift代码:

    // 创建WKWebView    let webView = WKWebView(frame: UIScreen.mainScreen().bounds)    // 设置访问的URL    let url = NSURL(string: "http://www.jianshu.com")    // 根据URL创建请求    let requst = NSURLRequest(URL: url!)    // WKWebView加载请求    webView.loadRequest(requst)     // 将WKWebView添加到视图    view.addSubview(webView)

可以看到很简单,和UIWebView并没有多少差别,然而性能就刷刷刷的提上去了,是不是很爽呢?如果你只是简单的集成个Web页到App,这些已经够了。不过很多时候并没有那么简单,还需要处理各种东西,那么接着往后看。


WKWebViewJavaScript的交互

WebKit框架中,有WKWebView可以替换UIKitUIWebViewAppKitWebView,而且提供了在两个平台可以一致使用的接口。WebKit框架使得开发者可以在原生App中使用Nitro来提高网页的性能和表现,Nitro就是SafariJavaScript引擎,WKWebView不支持JavaScriptCore的方式但提供message handler的方式为JavaScript与Native通信。(这个引自天狐博客,更多的与UIWebView或者WKWebView的交互方法可以在这里看到。下面部分代码(例如JS)也是窃取这个作者的,尊重原著,所以把原博客地址放这里,与JS交互写的比我好多了。)

Native调用JavaScript方法

原生调用JavaScript的代码需要在页面加载完成之后,就是在 - webView:didFinishNavigation:代理方法里面
OC代码:

[webView evaluateJavaScript:@"showAlert('奏是一个弹框')" completionHandler:^(id item, NSError * _Nullable error) {        // Block中处理是否通过了或者执行JS错误的代码    }];

Swift代码:

webView.evaluateJavaScript("showAlert('奏是一个弹框')") { (item, error) in            // 闭包中处理是否通过了或者执行JS错误的代码        }   

大家可以看到这段JS代码是最简单的弹出一个Alert的代码,后面WKWebView加载POST请求参数问题中还会有一个加载POST请求的JS代码,先不要管它了,请各位看官继续往后翻,看看JavaScript怎么调用Native的方法。

JavaScript调用Native方法

  • JavaScript的配置

    JavaScript调用Native的方法就需要前端和Native的小伙伴们配合了,需要前端的小伙伴在JS的方法中调用:

    window.webkit.messageHandlers.NativeMethod.postMessage("就是一个消息啊");

    这行代码。请注意,这个NativeMethod是和App中要统一的,配置方法将在下面的Native中书写。

  • Native App的代码配置

    下面该Native的代码的配置了,细心的小伙伴可能已经发现了,创建WKWebView的时候,除了有- initWithFrame:方法外,还有一个高端的方法:- initWithFrame:configuration:方法。那句名言是谁说的来着:普通玩家选择推荐配置,高端玩家选择自定义配置,就当是我说的吧(那个拿鞋的把鞋穿上吧,我承认不是我说的