WKWebView 您应该了解的七件事 - Jeremy Wie
iOS 中最初有 UIWebView.
什么是 UIWebView ?
-
iOS 2.0 中引入的原始 Web 渲染组件,
-
这是过去用来构建混合应用程序或在 iOS 应用程序中加载Web内容的 UI 控件.
-
UIWebView !== Safari
-
移动
Safari
的页面加载速度通常比UIWebView
快2-3
倍 -
应用于
Safari
的更改和修复程序通常不会
移植到UIWebView
中 -
UIWebview
笨拙,崩溃,内存泄漏 -
滚动阻止图像加载和动画播放
-
与
Safari
是不同的JavaScript
引擎, 没有Nitro
.
为什么 UIWebView 没有 Nitro ?
-
我们通常认为
Nitro
被排除在外是因为Apple希望降低混合应用程序的性能,并迫使所有人使用其本机平台. -
真实情况是由于
安全
原因而被排除在外。运行即时
编译器需要将RAM
中的页面标记为可执行文件 , iOS出于安全考虑不允许这样做,Safari
除外.
WKWebView 简介
-
WKWebView
在 iOS 8 中引入,为开发人员提供了出色的 Web 视图(与Safari“相同”的性能). -
WKWebView
的渲染全部在WKWebView
自己的单独进程
中完成. 就是说这个进程是独立于 App 进程之外的. WKWebView == WebKit
WKWebView == WebKit
WKWebView 的优点 (与 UIWebView 相比)
- 对 HTML 5 更好的支持.
image.png
- WebGL应用程序中的显着性能提升,
- 当 HTML / CSS / JavaScript 触发渲染错误时,减少 App 崩溃的情况. 由于与 App 在不同的进程, 所以最多就是白屏, 而不会引发 App 崩溃.
-
JavaScript
和页面渲染更快, 归功于 Nitro . - 60fps 交互式滚动
- Swift 和 JS 之间的更好交互
- 由于与
Safari
共享JS引擎
,因此WKWebView
会得到更好的维护并且更加可靠.
如何使用 WKWebView 呢?
-
以前是单个类(
UIWebView
)和协议(UIWebViewDelegate
). -
现在是
14
个类和3
个协议(WKNavigationDelegate
,WKScriptMessageHandler
,WKUIDelegate
), -
除了类文档(和
StackOverflow
) 外,Apple 没有官方的说明文档. -
需要更多代码
由 UIWebView 自动处理
1 应用商店链接
2 JS警报,确认,输入
3 在网络视图之间共享Cookie
WKWebView 相关类
WKBackForwardList
WKBackForwardListItem
WKFrameInfo
WKNavigation
WKNavigationAction
WKNavigationResponse
WKPreferences
WKProcessPool
WKScriptMessage
WKSecurityOrigin
WKUserContentController
WKUserScript
WKWebViewConfiguration
WKWebsiteDataRecord
WKWebsiteDataStore
WKWindowFeatures
WKWebView
WKWebView 的 7 个让人失望之处
先把这 7 个问题列出来, 再去逐个看如何解决.
- 无法在iOS 8中加载
bundled
内容 - 无法拦截POST请求
- UI 状态无法保存
- 死亡白屏
- 视图出现在中途
- 视图只有在可见时才会渲染
- iOS 8中的证书损坏或自签名
如何解决这 7 个问题呢 ?
接下来一个一个来解决
1. 无法在iOS 8中加载 bundled
内容, 这对许多应用程序至关重要.
-
UIWebView
:
webView.loadRequest(request)
(swift) -
WKWebView
高级方案: 将需要加载的文件复制到/tmp
目录中,我们可以从中加载文件
备选方案:从应用程序中的Web服务器提供我们需要的文件
解决方案:iOS 9 中已修复
2. 无法拦截 POST 请求
发送给代理方法的 NSURLRequest
中缺少POST
正文
解决方案:现在就离开-与Android行为保持一致
好消息:WebKit
论坛表明这是一个错误,似乎有点吸引人
3. UI 状态无法保存
WKWebView
不符合状态保存 API
(没有restoreIdentifier
)
在Astro
中,它用于减少内存占用并防止崩溃
解决方案:通过保存最近的已知 URL
来构建自己的 URL
4. 死亡白屏
向后浏览时,无缘无故地看到一些 Web 视图显示空白
似乎是内存问题
我们轮询我们管理且当前不可见的每个Web视图(在视图层次结构中)
5. 视图出现在中途
发生加载完成前未设置 frame 时,
必须在这一方面有创造力。
原来,重复的<head>标签被忽略了...
...所以我们在开头创建了一个<head>标签,只需向上滚动即可
6. 视图只有在可见时才会渲染
在标签栏布局中预加载标签的大问题
如果您依靠Javascript
在这些Webview中运行,则会出现更大的问题
解决方案: 使用屏幕外的“holding pen”处理当前不可见的网络视图
- iOS 8中的证书损坏或自签名
WKWebView
中的错误,其中记录在案的 SSL证书
自定义分析方法被破坏了
永远不会调用webView(_:didReceiveAuthenticationChallenge:completionHandler:)
内部使用很重要
没有解决方法
其他 bug
需要了解以下内容:
- 当应用程序在后台运行时,
JS
将在约10秒内
停止执行,而本机代码(以及UIWebView中的JS)将保持运行约3分钟,直到被操作系统完全挂起。 - 与UIWebView不同,webView.URL属性更新为导航目标,第一个委托方法由WKWebView调用。
- 应用商店链接默认情况下不起作用 - 必须拦截请求
本文翻译 Jeremy Wiebe 的 <WKWebView in Production 7 things you should know about>
如果读者发现有什么不妥之处, 请帮忙指出, 感谢 !