webview回调怎么解决

首页 > 实用技巧 > 作者:YD1662023-07-08 23:27:56

Networking 进程启动规则

Networking 规则相对简单,确保在 App 生命周期内启动一例(Crash 之后会重新创建)。相关代码:

webview回调怎么解决,(9)

三 主要问题与解决方案

WKWebView 在生产环境使用中,除去相对简单的使用和适配问题外,容易对开发者和前端同学造成困扰的问题有 4 个:

下面分别对这 4 例问题产生的原因、可尝试的解决方案以及不同方案下引入的问题做一下说明。

1 请求代理问题

这一点应该是阻碍 WKWebView 铺开的首要问题。问题背景也相对简单,并非有什么技术实现上的难度,而是苹果官方不希望 WKWebView 请求被应用拦截,美其名曰"为了安全"。但在实际使用场景中,我们又需要对 WebView 的请求进行代理以满足业务和性能诉求,典型场景如:离线包、流量监控等。

官方不支持、业务上又有使用场景,我们只能尝试通过"黑魔法"来解决。目前适用面比较多的解决方案有两个:

目前两种解决方案的实现方法都有较为丰富的资料和说明,在此不在赘述。

虽然这两种方案某种程度上可以"部分解决问题",但带来的副作用相对也不少,在生产环境中如何取舍还需具体开发同学来取舍。下面分别通过 "代理方案1" 和 "代理方案2" 代指来简单说明下,可以供大家选型时做一个参考。

代理方案 1

此为最早出现的 WKWebView 请求代理方案,可满足 iOS 9 及以后应用使用(目前最新为 iOS 14)。根据之前调研分析,业界大部分有代理需求的 App 采用此方案或变种方案。

1)方案思路

通过 WKBrowsingContextController 将 http(s) 注册到 Networking 的 m_registeredSchemes 数组中。对于数组中的 Scheme,WebKit 在发起请求时会通过 WKCustomProtocol 将请求发送到 App 所在的进程,并由 App 进程来执行发送。

由于从 Networking 进程将数据发送到 App 进程时,WebKit 内有意剥离了 Body 部分(见 WebCoreArgumentCodersMac.mm):

webview回调怎么解决,(10)

故需要对携带 body 的请求做一些特殊处理。处理方案是通过在 WKWebView 内注入脚本,重写掉 WebView 内请求发送相关方法。在请求发送之前将 body 部分序列化之后通过 bridge 传递到 App 进程暂存。

App 进程代理 WKWebView 请求时,根据规则按需拼接缓存的 body,完成之后再进行发送动作。

2)方案弊端

此方案虽然适用面较广,但是弊端也很明显。主要有两方面:

(1)问题一:无法定向处理、只能一刀切即如果 App 采用此方案,对其所有 WKWebView 实例的发送的请求都需要代理。如果有 WKWebView 实例中并未注入脚本或者执行代理,则可能导致请求无法发送、发送缺少 body 等问题,常见于一些集成的二方库、三方库中的 WKWebView 实例。

(2)问题二:重写脚本完备性很难保障由于需要在 JS 层重写请求发送逻辑,比如 form 表单提交、AJAX、Fetch 等接口,重写接口的质量直接决定方案的完备度。且 WKWebView 原设计有不少能力在 c 层面实现,仅在 JS 重写无法保证对齐。目前已知的问题有:

代理方案 2

此方案是基于苹果在 iOS 11 上开放的 [WKWebViewConfiguration setURLSchemeHandler:forURLScheme:] 接口做"扩展"来实现。对于 iOS 11.3 以后的设备,此方案具备较好实用性(WebKit 处理了部分 Body 传递问题)。

1)方案思路

2)方案优势

代理方案 2 相对方案 1 两个巨大的优势在于:

3)方案弊端

此方案除去有 iOS 11.3 的系统版本限制外,在具体运行中也有也有不少很难处理的问题,主要如下:

(1)问题一:多图分片下载情况下,WKWebView 内部存在处理时序存在 BUG

问题表现:在 WKWebView 中加载大图、且大图数据存在存在分片返回时,WKWebView 内部时序处理异常可能导致 图片无法展示、图片展示不完整等问题。具体可结合 WebKit 中对图片加载的流程来简单说明下:

webview回调怎么解决,(11)

问题即出现在上述 step1, step2, step3 的执行顺序上。在异常情况下,会偶现执行顺序为:step1 -> step3 -> step2, 且 step3 不再被触发(allDataReceived),进而导致图片最终的内容未渲染上屏。

解决方案:目前暂无有效的解决办法,通过配置 suppressesIncrementalRendering 配置为 YES 某种程度上可以缓解问题,但并无法根治且对体验略有影响。

(2)问题二:iOS 12及以下系统系统同步 AJAX 导致 Crash

问题表现:在 WKWebView 中如果出现 Web 页面发送 sync request,则可导致 WebContent 进程崩溃,WKWebView 回调 webViewWebContentProcessDidTerminate,进而导致页面白屏等问题。此问题可明确是 WebKit 内部的 BUG,且已有相关 Fix:

Bug1: WebURLSchemeHandlerProxy::loadSynchronously crash with sync request(2018-08-06 14:14 ):https://bugs.webkit.org/show_bug.cgi?id=188358

Bug2: WKURLSchemeHandler crashes when sent errors with sync XHR(2019-06-20 01:20):https://bugs.webkit.org/show_bug.cgi?id=199063

处理方案:对于 Bug1,处理相对比较简答,即在网络请求回调 error 之前优先回调部分空数据,规避掉问题;但是对于 Bug2,目前缺少有效的解决办法。

(3)问题三:301 请求下 SWAP 导致页面无法转场问题

问题表现:如果页面中存在使用 301 做重定向的情况,可能会出现重定向页面无法加载的情况,进而导致页面异常、白屏等问题。

处理方案:关闭 processSwapsOnNavigation,将置为 NO(内部属性)。

总的来说,虽然代理方案 2 相比代理方案 1 有很大的优势,但此方案因为版本限制等原因,目前使用量相比代理方案 1 略低。且与代理方案 1 相比,此方案的优势和劣势都很明显,如多图分片场景下可能导致图片无法展示的问题,目前未找到有效的解决办法。方案 2 是否可替代方案 1 在生产环境使用,还需使用同学自己斟酌。

2 Cookie 问题

根据官方文档及资料,我们可知 WKWebView 因为其"独立存储",导致 Cookie 和 Cache 与 App 不互通,进而有问题。但是这种表述较为模糊,且实际使用中 WKWebView 与 App 的 Cookie 并非完全隔离,这种模棱两可的表现很难让人搞清楚"通"或"不通"的边界在哪里。

下面首先根据自己对这块的理解,尝试说明下 WKWebView 使用 Cookie 问题到底是什么、以及背后的原因。由于苹果并未对全部代码开源,下有不少内容是自己的理解和推断,无法保证完全正确,仅介绍部分思路和判断,供大家在需要时参考。

Cookie 管理策略

根据上节的背景介绍我们可知,iOS Cookie 相关内容,是在 CFNetwork 这一层由 CFHTTPCookie、CFHTTPCookieStorage 等来管理,是 CFNetwork 模块的一部分。且对于 Session Cookie 和 持久化 Cookie,系统有着不同的管理策略:

WKWebView Cookie 问题

基于上节的 iOS Cookie 管理、结合多进程模型,我们大概可以推断 App 与 WKWebView Cookie 管理模型,见如下简图:

webview回调怎么解决,(12)

上一页1234下一页

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.