WKWebView。 我的经验
从iOS 8开始,我们(iOS开发人员)使用WKWebView替代UIWebView。 即使看起来非常简单(加载HTML并在特殊视图中呈现),webViews在使用它们时也会遇到问题。
在本文中,我想分享一些有关在iOS项目中使用WebView的想法。
问题
乍一看,webView应该不难。 如渲染一些HTML或通过URL加载网页。 但是在iOS中使用WKWebView可能很容易成为一项艰巨的任务。 我试图将我的经验分为四个部分:
- Cookie管理
- 终止内容过程
- 记忆问题
- 信息清单🙂
饼干
加载页面时,将在webView中加载URLRequest的实例。 WebView通过它的ProcessPool处理它的cookie,您不需要中断它的工作。
要通过WKWebView接收HTTP标头和cookie(cookie是HTTP标头之一),您应该实现WKNavigationDelegate方法
如果您想在特定时间检查webViews cookie,则可以通过Safari Web Inspector(首先在iPhone设置中启用JavaScript调试)进行检查。 HTTPCookieStorage通常与Safari不同步。
如前所述,cookie,缓存和所有此类资源均由webView的WKProcessPool实例处理。 如果您需要在不同的webView之间共享cookie,而不是在其配置中共享相同的进程池。
如果您确实需要注入自己的cookie,则分两个步骤进行。
- 创建URLRequest实例时,在相应的标题字段中设置Cookie
- 加载了WKUserScript的页面后,使用javascript“注入”您的cookie
这就是具有这种逻辑的UIViewController的方式
在处理重定向和更改cookie时要小心。 在重定向期间,webView使用其内部cookie状态,而不是您在第一次加载时通过的状态。 例如:
- 您在URLRequest中设置自定义cookie,然后将其加载到webView中。
- WebView接收代码30x(重定向),服务器通过标头设置其cookie。
- WebView根据其内部状态构建新的URLRequest。 您的Cookie可能丢失了。 与查尔斯检查
最后,关于cookie,我建议您将cookie逻辑留给webView,如果您需要服务器跟踪应用程序的请求,则可以通过设置自定义用户代理来实现。 通过设置
通过UserDefaults iOS可以确保您每个HTTP请求都具有该用户代理。
终止内容过程
其基础Web内容处理已终止的Web视图。
对您的用户意味着什么? 意思是“死亡白屏”。 您的用户看不到任何内容。 触发“重新加载”方法无效。 WebViews属性URL设置为nil。 您应该跟踪此事件,并尝试恢复您的webView,加载最后一个已知的URL或重新创建webView。
当您使用困难的JS加载页面或上传大量媒体(例如高分辨率图片)时,可能会出现此事件。
记忆问题
WKWebView API并不完美。 如果您使用webView构建复杂的内容,请检查是否存在内存泄漏。
例如,如果要跟踪监听JS代码,则需要将WKScriptMessageHandler添加到WKUserContentController中:
但是内容控制器对他的脚本消息处理程序拥有很强的引用。 这意味着,如果将消息处理程序设置为WebView本身或viewController,则将收到一个保留周期。 您应该将消息处理程序包装到弱引用容器中,如下所示
并添加这样的脚本消息处理程序
信息清单
如果将WKWebView添加到您的项目中,则将这些键及其描述添加到info.plist中(适用于iOS 11),否则会崩溃。 我有很多。
最后的想法
我不会说任何webView都是好的。 我只是想分享一些经验,这对其他开发人员有所帮助。
如果您想使用跨平台解决方案,请使用Flutter或React Native。 当您需要在本机应用程序中使用一些原型时,或者实际上必须渲染一些HTML时,请使用webView,但不要从中汲取教训。
- 在MKMapView中,用户看不到所有注释
- 在放大时使用MKMapView在setUserTrackingMode上崩溃
- UITableViewCell +dynamic高度+自动布局
- 如何将UIView渲染成CGContext
- 什么时候适合使用自动更新订阅 – iOS
- OAuthGetRequestToken:signature_invalid错误
- SpriteKit SKTextureAtlas,由于加载纹理时的内存压力而终止
- embedded到UINavigationBar / Item中的UISegmentedControl
- 我可以用addOperationWithBlock取消添加到NSOperationQueue的Block吗?