偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

iOS 端容器之 WKWebView 那些事

網(wǎng)絡(luò)
熟悉 iOS\macOS Hybrid 混合開發(fā)的同學(xué)應(yīng)該都有體會,WKWebView 雖然是蘋果作為替代 UIWebView\WebView 而推出的"新"組件,但大部分開發(fā)者對它實在“愛不起來”。畢竟對于國內(nèi)大部分應(yīng)用開發(fā)者來說,在實際使用中 WKWebView 所謂的“優(yōu)勢”未必能體現(xiàn)出來,但帶來的“坑”卻都著實都不淺。

 [[413463]]

一 背景

熟悉 iOS\macOS Hybrid 混合開發(fā)的同學(xué)應(yīng)該都有體會,WKWebView 雖然是蘋果作為替代 UIWebView\WebView 而推出的"新"組件,但大部分開發(fā)者對它實在“愛不起來”。畢竟對于國內(nèi)大部分應(yīng)用開發(fā)者來說,在實際使用中 WKWebView 所謂的“優(yōu)勢”未必能體現(xiàn)出來,但帶來的“坑”卻都著實都不淺。

目前社區(qū)或線上可查找的 WKWebView 相關(guān)資料,大多比較陳舊且人云亦云、復(fù)制粘貼類的居多。少部分真實實踐和探索的開發(fā)者,或許也因時間或精力的原因,對問題和解決方案未能做詳細的闡述。導(dǎo)致目前線上 WKWebView 相關(guān)的資料數(shù)量不少、但質(zhì)量不高;且有不少文章存在對問題的背景解釋不清,解決方案缺乏有效驗證等問題。

我從事端容器領(lǐng)域開發(fā)多年,曾在生產(chǎn)環(huán)境方案設(shè)計上與 WKWebView "對抗"多次。目前混合開發(fā)已經(jīng)是現(xiàn)代 App 標配,一方面是對這么長時間用法經(jīng)驗上的總結(jié),另外一方面也希望能夠為還在抗爭中的同學(xué)提供一些新視角或者解決思路,故準備結(jié)合 WebKit 部分源碼,將自己對這個組件的理解以及部分問題解決方案整理分享一下。本文嘗試說明 3 件事情:

WKWebView 使用中的典型問題有哪些

為什么會出現(xiàn)這些問題

這些問題的解決辦法有哪些

二 基礎(chǔ)回顧

iOS 端網(wǎng)絡(luò)設(shè)計和 WKWebView 設(shè)計特點我們可以通過官方資料來查閱。但為了后面更好的說明問題,下面我們重點回顧下與文章后續(xù)內(nèi)容相關(guān)的兩個基本知識點:

iOS 端網(wǎng)絡(luò)設(shè)計與 Cookie 管理

WKWebView 多進程模型

1 iOS 網(wǎng)絡(luò)設(shè)計與 Cookie 管理

Cookie 管理是做混合開發(fā)過程中經(jīng)常會涉及到的部分,在應(yīng)用開發(fā)中我們知道可以通過 NSHTTPCookie 和NSHTTPCookieStorage 來管理應(yīng)用的 Cookie。但在系統(tǒng)層面 Cookie 是如何管理的、如何與網(wǎng)絡(luò)層各模塊進行聯(lián)動,這對我們后面分析WKWebView 中的 Cookie 問題有著至關(guān)重要的聯(lián)系。

根據(jù)官方資料,我們可知 iOS 平臺下網(wǎng)絡(luò)相關(guān)模塊大概關(guān)系如下:

從上至下模塊依次為:

WebKit:應(yīng)用層,客戶端 App 以及 WKWebView 處于這一層。
NSURL:可以理解為對底層 CF 接口的封裝擴展層,NSURLConnection、NSURLSession 等處于這一層。
CFNetwork:iOS 網(wǎng)絡(luò)模塊核心實現(xiàn)層,是網(wǎng)絡(luò)層設(shè)計中最重要的部分。負責(zé)網(wǎng)絡(luò)協(xié)議組裝發(fā)送接收等主要工作,與 CoreFoundation 框架關(guān)系緊密。
BSD socket:基于底層硬件接口的 socket 服務(wù)。
CFNetwork 是整個網(wǎng)絡(luò)系統(tǒng)的核心模塊,負責(zé)組裝請求、處理響應(yīng)等:

核心內(nèi)容包含:

CFURLRequest:包括 URL/header/body 這些請求的信息。CFURLRequest 會進一步轉(zhuǎn)換成 CFHTTPMessage。
CFHTTPMessage:主要是 HTTP 協(xié)議的定義和轉(zhuǎn)換,把每一個請求 request 轉(zhuǎn)換成標準的 HTTP 格式的文本。
CFURLConnection:主要是處理請求任務(wù)。包括 pthread 線程、CFRunloop、請求隊列的管理等等。提供了start、cancel 等等操作的 API。
CFHost:負責(zé) DNS,有 CFHostStartInfoResolution 等函數(shù),基于 dns_async_start 和 getaddrinfo_async_start 等方法。
CFURLCache/CFURLCredential/CFHTTPCookie:處理 緩存/證書/cookie 相關(guān)的邏輯,都有對應(yīng)的NS類。
從上面分析可知關(guān)鍵信息:iOS Cookie 管理相關(guān)模塊處于 CFNetwork 這一層中。即對于請求 Response 中的 "set-cookie" 字段,在 CFNetwork 中被消費和處理。

2 WKWebView 多進程模型

通過官方資料,我們知道 WKWebView 相比 UIWebView 很大的一個變化是"多進程模型":

WKWebView 在運行時,核心模塊運行在獨立進程中,與 App 進程獨立。

WKWebView 使各種問題的原因,有不少和多進程運行模式有很大的關(guān)系。

多進程模型詳解

但具體是什么樣形態(tài)的多進程?我們通過一張簡圖來說明下:

WKWebView(WebKit) 包含 3 種進程:UI Process, Networking Process, WebContent Process。
UI Process:即 App 進程,WKWebView(WebKit) 中部分模塊運行在此進程,會負責(zé)啟動其它進程。
Networking Process:即網(wǎng)絡(luò)模塊進程,主要負責(zé) WKWebView 中網(wǎng)絡(luò)請求相關(guān)功能;此進程 App 中只會有啟動一次,多個 WKWebView 間共享。
WebContent Process:即 Web 模塊進程,主要負責(zé) WebCore, JSCore 相關(guān)模塊的運行,是 WKWebView 的核心進程。此進程在 App 中會啟動多次,每個 WKWebView 會有自己獨立的 WebContent 進程。
各個進程之間通過 CoreIPC 進程通信。
總的來說:在一個客戶端 App 中,多個 WKWebView 使用中會共享一個 UI 進程(與 App 進程共享)、共享一個 Networking 進程、每個 WKWebView 實例獨享一個 WebContent 進程。

示例:

此處關(guān)于 WebContent Process 和 Networking Process 的啟動規(guī)則,官方文檔并未解釋特別清楚,且因為版本迭代等原因,文檔與目前最新規(guī)則也略有出入。為避免混淆與歧義,下面結(jié)合 WebKit 源碼稍作分析。

WebContent 進程啟動規(guī)則

根據(jù)官方文檔描述:

A WKProcessPool object represents a single process that WebKit uses to manage web content. To provide a more secure and stable experience, WebKit renders the content of web views in separate processes, rather than in your app’s process space. By default, WebKit gives each web view its own process space until it reaches an implementation-defined process limit. After that, web views with the same WKProcessPool object share the same web content process.

規(guī)則是優(yōu)先使用創(chuàng)建新進程,當(dāng)進程上線超過某閾值之后則會共享,在 WebKit 內(nèi)部由 maximumProcessCount 控制。但是此規(guī)則只對 iOS13 之前的系統(tǒng)生效,iOS13 之后的系統(tǒng),WKWebView 每次創(chuàng)建實例都會啟動一個新的 WebContent Porcess。相關(guān)實現(xiàn)如下。

iOS13 前:

iOS 13 及以后:

Networking 進程啟動規(guī)則

Networking 規(guī)則相對簡單,確保在 App 生命周期內(nèi)啟動一例(Crash 之后會重新創(chuàng)建)。相關(guān)代碼:

三 主要問題與解決方案

WKWebView 在生產(chǎn)環(huán)境使用中,除去相對簡單的使用和適配問題外,容易對開發(fā)者和前端同學(xué)造成困擾的問題有 4 個:

請求代理問題
Cookie 管理問題
全面屏適配問題
WebContent 進程崩潰問題
下面分別對這 4 例問題產(chǎn)生的原因、可嘗試的解決方案以及不同方案下引入的問題做一下說明。

1 請求代理問題

這一點應(yīng)該是阻礙 WKWebView 鋪開的首要問題。問題背景也相對簡單,并非有什么技術(shù)實現(xiàn)上的難度,而是蘋果官方不希望 WKWebView 請求被應(yīng)用攔截,美其名曰"為了安全"。但在實際使用場景中,我們又需要對 WebView 的請求進行代理以滿足業(yè)務(wù)和性能訴求,典型場景如:離線包、流量監(jiān)控等。

官方不支持、業(yè)務(wù)上又有使用場景,我們只能嘗試通過"黑魔法"來解決。目前適用面比較多的解決方案有兩個:

通過 [WKBrowsingContextController registerSchemeForCustomProtocol:] 來注冊代理,為方便簡稱為代理方案1。
通過 [WKWebViewConfiguration setURLSchemeHandler:forURLScheme:] 來注冊,為方便簡稱為代理方案 2。
目前兩種解決方案的實現(xiàn)方法都有較為豐富的資料和說明,在此不在贅述。

雖然這兩種方案某種程度上可以"部分解決問題",但帶來的副作用相對也不少,在生產(chǎn)環(huán)境中如何取舍還需具體開發(fā)同學(xué)來取舍。下面分別通過 "代理方案1" 和 "代理方案2" 代指來簡單說明下,可以供大家選型時做一個參考。

代理方案 1

此為最早出現(xiàn)的 WKWebView 請求代理方案,可滿足 iOS 9 及以后應(yīng)用使用(目前最新為 iOS 14)。根據(jù)之前調(diào)研分析,業(yè)界大部分有代理需求的 App 采用此方案或變種方案。

1)方案思路

通過 WKBrowsingContextController 將 http(s) 注冊到 Networking 的 m_registeredSchemes 數(shù)組中。對于數(shù)組中的 Scheme,WebKit 在發(fā)起請求時會通過 WKCustomProtocol 將請求發(fā)送到 App 所在的進程,并由 App 進程來執(zhí)行發(fā)送。

由于從 Networking 進程將數(shù)據(jù)發(fā)送到 App 進程時,WebKit 內(nèi)有意剝離了 Body 部分(見 WebCoreArgumentCodersMac.mm):

故需要對攜帶 body 的請求做一些特殊處理。處理方案是通過在 WKWebView 內(nèi)注入腳本,重寫掉 WebView 內(nèi)請求發(fā)送相關(guān)方法。在請求發(fā)送之前將 body 部分序列化之后通過 bridge 傳遞到 App 進程暫存。

App 進程代理 WKWebView 請求時,根據(jù)規(guī)則按需拼接緩存的 body,完成之后再進行發(fā)送動作。

2)方案弊端

此方案雖然適用面較廣,但是弊端也很明顯。主要有兩方面:

(1)問題一:無法定向處理、只能一刀切即如果 App 采用此方案,對其所有 WKWebView 實例的發(fā)送的請求都需要代理。如果有 WKWebView 實例中并未注入腳本或者執(zhí)行代理,則可能導(dǎo)致請求無法發(fā)送、發(fā)送缺少 body 等問題,常見于一些集成的二方庫、三方庫中的 WKWebView 實例。

(2)問題二:重寫腳本完備性很難保障由于需要在 JS 層重寫請求發(fā)送邏輯,比如 form 表單提交、AJAX、Fetch 等接口,重寫接口的質(zhì)量直接決定方案的完備度。且 WKWebView 原設(shè)計有不少能力在 c++ 層面實現(xiàn),僅在 JS 重寫無法保證對齊。目前已知的問題有:

對于同步請求,此方案目前無法支持。
對于流式請求,比如上傳場景,目前支持度較差。只能在 JS 側(cè)全量讀取之后再進行發(fā)送。
無法處理 Fetch API Stream 返回值。
當(dāng)使用 Form 表單提交內(nèi)容包含大塊數(shù)據(jù)時,可能出現(xiàn)丟失、Crash 等情況。

代理方案 2

此方案是基于蘋果在 iOS 11 上開放的 [WKWebViewConfiguration setURLSchemeHandler:forURLScheme:] 接口做"擴展"來實現(xiàn)。對于 iOS 11.3 以后的設(shè)備,此方案具備較好實用性(WebKit 處理了部分 Body 傳遞問題)。

1)方案思路

[WKWebViewConfiguration setURLSchemeHandler:forURLScheme:] 可以在 WKWebView 實例上注冊自定義請求 Scheme。如果 WKWebView 發(fā)送的請求匹配注冊 Scheme,則會代理到 UI 進程(App 進程) 執(zhí)行發(fā)送動作。
WKWebView 內(nèi)部默認不支持注冊 http(s) 等標準 Scheme,但是有"黑魔法"可繞過限制。
對于 AJAX 發(fā)送 BLOB 數(shù)據(jù)時,也會出現(xiàn) body 丟失的情況,可以參考 代理方案1 中類似的方案來解決。
2)方案優(yōu)勢

代理方案 2 相對方案 1 兩個巨大的優(yōu)勢在于:

不用一刀切,配置與 WKWebView 實例綁定:即可以定向處理我們需要處理的 WKWebView 實例,對于 三方庫 中的對象,完全可以做到無影響,安全性大大提高。
不用重寫所有發(fā)送請求:大部分情況下請求中的 body 是可以被攜帶到 App 進程,即我們只需定向處理部分異常即可,健壯性大大提升。
3)方案弊端

此方案除去有 iOS 11.3 的系統(tǒng)版本限制外,在具體運行中也有也有不少很難處理的問題,主要如下:

(1)問題一:多圖分片下載情況下,WKWebView 內(nèi)部存在處理時序存在 BUG

問題表現(xiàn):在 WKWebView 中加載大圖、且大圖數(shù)據(jù)存在存在分片返回時,WKWebView 內(nèi)部時序處理異??赡軐?dǎo)致 圖片無法展示、圖片展示不完整等問題。具體可結(jié)合 WebKit 中對圖片加載的流程來簡單說明下:

問題即出現(xiàn)在上述 step1, step2, step3 的執(zhí)行順序上。在異常情況下,會偶現(xiàn)執(zhí)行順序為:step1 -> step3 -> step2, 且 step3 不再被觸發(fā)(allDataReceived),進而導(dǎo)致圖片最終的內(nèi)容未渲染上屏。

解決方案:目前暫無有效的解決辦法,通過配置 suppressesIncrementalRendering 配置為 YES 某種程度上可以緩解問題,但并無法根治且對體驗略有影響。

(2)問題二:iOS 12及以下系統(tǒng)系統(tǒng)同步 AJAX 導(dǎo)致 Crash

問題表現(xiàn):在 WKWebView 中如果出現(xiàn) Web 頁面發(fā)送 sync request,則可導(dǎo)致 WebContent 進程崩潰,WKWebView 回調(diào) webViewWebContentProcessDidTerminate,進而導(dǎo)致頁面白屏等問題。此問題可明確是 WebKit 內(nèi)部的 BUG,且已有相關(guān) 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,處理相對比較簡答,即在網(wǎng)絡(luò)請求回調(diào) error 之前優(yōu)先回調(diào)部分空數(shù)據(jù),規(guī)避掉問題;但是對于 Bug2,目前缺少有效的解決辦法。

(3)問題三:301 請求下 SWAP 導(dǎo)致頁面無法轉(zhuǎn)場問題

問題表現(xiàn):如果頁面中存在使用 301 做重定向的情況,可能會出現(xiàn)重定向頁面無法加載的情況,進而導(dǎo)致頁面異常、白屏等問題。

處理方案:關(guān)閉 processSwapsOnNavigation,將置為 NO(內(nèi)部屬性)。

總的來說,雖然代理方案 2 相比代理方案 1 有很大的優(yōu)勢,但此方案因為版本限制等原因,目前使用量相比代理方案 1 略低。且與代理方案 1 相比,此方案的優(yōu)勢和劣勢都很明顯,如多圖分片場景下可能導(dǎo)致圖片無法展示的問題,目前未找到有效的解決辦法。方案 2 是否可替代方案 1 在生產(chǎn)環(huán)境使用,還需使用同學(xué)自己斟酌。

2 Cookie 問題

根據(jù)官方文檔及資料,我們可知 WKWebView 因為其"獨立存儲",導(dǎo)致 Cookie 和 Cache 與 App 不互通,進而有問題。但是這種表述較為模糊,且實際使用中 WKWebView 與 App 的 Cookie 并非完全隔離,這種模棱兩可的表現(xiàn)很難讓人搞清楚"通"或"不通"的邊界在哪里。

下面首先根據(jù)自己對這塊的理解,嘗試說明下 WKWebView 使用 Cookie 問題到底是什么、以及背后的原因。由于蘋果并未對全部代碼開源,下有不少內(nèi)容是自己的理解和推斷,無法保證完全正確,僅介紹部分思路和判斷,供大家在需要時參考。

Cookie 管理策略

根據(jù)上節(jié)的背景介紹我們可知,iOS Cookie 相關(guān)內(nèi)容,是在 CFNetwork 這一層由 CFHTTPCookie、CFHTTPCookieStorage 等來管理,是 CFNetwork 模塊的一部分。且對于 Session Cookie 和 持久化 Cookie,系統(tǒng)有著不同的管理策略:

Session Cookie:內(nèi)存中保存,進程周期內(nèi)生效。在 iOS 移動端,一個 App 進程 即對應(yīng)于一個 Session,即 Session Cookie 可在進程內(nèi)共享。
持久化 Cookie:這部分 Cookie 除保存內(nèi)存以外,還會持久化到磁盤,可多次使用。本地文件存儲在 沙箱文件夾/Library/Cookies/Cookies.binarycookies;需要特別注意的是:持久化 Cookie 并非在產(chǎn)生之后立即同步到 Cookies.binarycookies,根據(jù)經(jīng)驗會有一個 300ms ~ 3s 的延遲。

WKWebView Cookie 問題

基于上節(jié)的 iOS Cookie 管理、結(jié)合多進程模型,我們大概可以推斷 App 與 WKWebView Cookie 管理模型,見如下簡圖:

注意:WKHTTPCookieStore 為示意,畫到了 Networking 進程,實際情況中此模塊分散在 WebContent、Networking 以及 UI Process 中,且各進程中的部分通過 IPC 橋接。

根據(jù)上圖可以引導(dǎo)出 WKWebView Cookie 相關(guān)的 2 個核心點:

1)WKWebView Cookie 問題具體是什么

對于 "Session Cookie":App 進程與 WKWebView 進程(WebContent + Networking)之間 完全隔離。
對于 "持久化 Cookie":App 進程與 WKWebView 進程(WebContent + Networking)之間 同步存在時差。
2)造成 WKWebView Cookie 問題的根本原因

App 進程 與 Networking 雙進程的設(shè)計。

核心目標

在了解 WKWebView 問題以及對應(yīng)的根本原因之后,如何來處理此問題相對也清晰了:根據(jù)是否采用代理了 WKWebView 的網(wǎng)絡(luò)請求,我們需要不同的處理策略。

場景 1 - 未代理 WKWebView 網(wǎng)絡(luò)請求:Cookie 完全由 Networking 進程管理,WKWebView 內(nèi)可自閉環(huán)。大部分情況下 App 進程也無需感知,如果確實需要感知,可以根據(jù)業(yè)務(wù)場景選擇 JS 橋接、強制持久化等方案。
場景 2 - 已代理 WKWebView 網(wǎng)絡(luò)請求:Cookie 大部分是由 App 進程來管理,此時應(yīng)該采用何種同步策略。
由于場景 1 中我們并未在生產(chǎn)環(huán)境中采用,故本文不打算做冒然分析。下面主要聚焦于場景 2 來做進一部分分析。在場景 2 下我們的核心目標:

對于 App 進程中產(chǎn)生的 Cookie,能夠及時同步到 Networking 進程:主要解決 Reponse 中存在 "Set-Cookie" 情況下,JS 端如何及時讀取相關(guān) Cookie 的問題。
對于 WebContent 中由 JS 產(chǎn)生的 Cookie,能及時同步到 App 進程:主要解決在 JS 端產(chǎn)生 Cookie 之后,我們?nèi)绾伪WC在后續(xù)代理的網(wǎng)絡(luò)請求中可被正常攜帶的問題。

同步手段

在確認方案之前,我們首先要搞清楚一個問題:客戶端側(cè) Cookie 來源有哪些?

對于 App 進程,Cookie 來源有兩個:

通過 NSHTTPCookieStorage 寫入的。
在網(wǎng)絡(luò)請求 Response Header 中通過 "Set-Cookie" 寫入的。
對于 WebContent 進程,主要是 JS 通過 document.cookie 寫入的(網(wǎng)絡(luò)代理之后 Set-Cookie 不會在 WKWebView 進程中生效)。

其次,我們要確認可用做同步的手段有哪些:

對于 iOS 11 之后的系統(tǒng),蘋果已經(jīng)為我們提供了 WKHTTPCookieStore 對象用來讀寫、監(jiān)聽 WKWebView 對應(yīng)的 Cookie,可以直接使用。

對于 iOS 11 之前的系統(tǒng),需要區(qū)分處理一下。

從 App 進程同步到 Networking 進程,簡單流程如下:

第1步,需要把 Session Cookie 持久化,臨時保存(注意需要標識,以供恢復(fù))。
第2步,調(diào)用 NSHTTPCookieStorage 內(nèi)部接口 _saveCookies 觸發(fā)強制同步。
第3步,恢復(fù)臨時保存的 Session Cookie,避免污染。
由于 Networking 進程不會產(chǎn)生 Cookie,所以我們下面要做的是從 WebContent 進程同步 Cookie:處理策略即在 JS 側(cè)重寫 document.cookie 方法,在 JS 修改 cookies 時,通過 bridge 將 cookie 傳遞到 App 進程。

處理方案

在理清楚問題、目標和可用手段之后,我們即可總結(jié)出 WKWebView Cookie 相關(guān)問題的處理方案:

對于 iOS 11 及之后的系統(tǒng),我們可以通過 HOOK NSHTTPCookieStorage 中讀寫 Cookie 的接口,并且監(jiān)聽網(wǎng)絡(luò)請求中 "Set-Cookie" 關(guān)鍵字,在 App 進程 Cookie 發(fā)生變化時同步到 WKWebView;同時通過 WKHTTPCookieStore 提供 cookiesDidChangeInCookieStore 能力來監(jiān)聽 WKWebView 中 Cookie 的變化。
對于 iOS 11 之前的系統(tǒng),處理策略類似。但是我們需要過 NSHTTPCookieStorage 接口來做強制同步,并且需要注意恢復(fù) Cookie 的 SessionOnly 屬性;同時需要通過在 JS 側(cè)重寫 document.cookie 的方式,來感知 WKWebView 中 Cookie 的變化。
特別注意:

采用 iOS 11 之后方案處理時一定要注意,對 WKHTTPCookieStore 的操作會 涉及到 IPC 通信,如果通信過于頻繁、通信數(shù)據(jù)量過大,會產(chǎn)生明顯的性能問題。極端情況可能造成 IPC 模塊異常,出現(xiàn)所有 WKWebView 都無法加載的情況。比如典型的場景,如果一個頁面請求較多、每個請求都帶"Set-Cookie"、且業(yè)務(wù)上為了簡單,每次把 App 進程的 Cookie 全量同步到 WKWebView,則 Cookie 過多時,有一定概率(暴力測試可復(fù)現(xiàn))觸發(fā) IPC 異常,導(dǎo)致后續(xù)所有 WKWebView 實例都無法正常加載,只有 App 殺進程才可恢復(fù)。建議在同步 Cookie 時,盡量按需同步變化的部分。

3 全面屏適配問題

全面屏適配問題相對不復(fù)雜,但因為 WKWebView 如 UIWebView 在表現(xiàn)上的不同,導(dǎo)致容易造成一些困擾。

問題是 UIWebView 與 WKWebView 在對前端 viewport-fit 支持表現(xiàn)上略有差別:UIWebView 對 viewport-fit 支持度較好,表現(xiàn)基本與官方文檔表述一致。但是 WKWebView 中存在一個潛規(guī)則,如果 Web 頁面內(nèi) body 的高度,在沒有超出 WKWebView 組件實際高度時,viewport-fit=cover 可能不生效。

處理辦法是在頁面中規(guī)避掉此類情況,如配置 body height 為 100vh (或其它類似方案)。

4 WebContent 進程崩潰問題

這是一個出現(xiàn)概率不高,但是缺乏通用、有效解決辦法的問題。我們知道 WKWebView 多進程模式下,如果 WebContent 進程因為各種原因出現(xiàn) Crash,則 WKWebView 會通過 webViewWebContentProcessDidTerminate 回調(diào)告訴開發(fā)者,一般情況下我們會通過 reload 方法重新加載頁面。同時如果用戶設(shè)備內(nèi)存緊張,則可能出現(xiàn)系統(tǒng)主動 KILL WebContent 進程的情況。即可能出現(xiàn) App 進程(前臺)正常,但是 WebContent 崩潰、頁面重新加載的情況。

絕大部分情況,進入此流程并不一定會對用戶操作造成困擾。但是,如果此時造成內(nèi)存緊張是因為前端觸發(fā)業(yè)務(wù)導(dǎo)致,典型如表單中喚起相機上傳圖片,此流程對用戶的影響可能是致命的。即使我們通過 WebView reload 使頁面恢復(fù),用戶在執(zhí)行的上傳動作也會被打斷,導(dǎo)致提交流程出現(xiàn)異常、影響用戶的操作。且如果用戶設(shè)備進入此狀態(tài),大部分情況下用戶再次操作還會觸發(fā)同樣的流程。

這種情況下,用戶無法及時感知到造成問題的根本原因,絕大多數(shù)直觀反應(yīng)即為:“App 出現(xiàn) bug 了!”故從用戶角度來看,缺少自動恢復(fù)、處理問題的辦法。

目前此問題缺乏有效、統(tǒng)一解決辦法,一種解決思路是客戶端與前端配置,針對核心、可能出現(xiàn)異常的流程,定向設(shè)計解決方案。通過端側(cè)的能力來將數(shù)據(jù)持久化,在類似異常發(fā)生之后使用持久化數(shù)據(jù)恢復(fù)現(xiàn)場,盡量在用戶無感的情況下保證用戶操作流程正常。

四 總結(jié)

以上便是我們在端容器設(shè)計開發(fā)過程中,WKWebView 使用上遇到的一些典型問題和對應(yīng)的解決辦法??偟膩碚f,目前造成這么不協(xié)調(diào)的狀態(tài),大部分是因為系統(tǒng)平臺未能充分考慮開發(fā)者訴求、組件設(shè)計對歷史業(yè)務(wù)兼容性不佳導(dǎo)致的。當(dāng)然,現(xiàn)在這種狀態(tài)必然也不是一種合理狀態(tài),未來無論是系統(tǒng)平臺方、還是業(yè)務(wù)方、或者是開發(fā)者,當(dāng)矛盾無法協(xié)調(diào)時總有一方要進行妥協(xié)。在這個時間點來臨之前,希望上面總結(jié)內(nèi)容,能夠為受此類問題困擾的同學(xué)提供一些幫助。

 

責(zé)任編輯:梁菲 來源: 阿里云云棲號
相關(guān)推薦

2015-09-14 09:16:17

iOS統(tǒng)計打點

2019-12-10 08:00:46

Kata容器Linux

2022-10-26 09:57:52

VectorRustC++

2020-08-11 08:59:20

容器虛擬化技術(shù)

2017-01-10 13:33:51

iOS編程throttle

2011-05-19 16:47:50

軟件測試

2012-05-01 08:06:49

手機

2017-05-15 21:50:54

Linux引號

2024-02-04 17:03:30

2017-04-06 09:35:10

大數(shù)據(jù)SparkSQLSpark

2015-05-28 14:02:09

JavaJava日志性

2011-08-22 16:42:43

SqliteiPad

2011-12-02 10:32:23

Java

2014-06-06 16:08:17

初志科技

2021-10-19 21:39:51

Unsafe構(gòu)造器內(nèi)存

2020-09-23 09:07:16

特權(quán)賬號管理PAM網(wǎng)絡(luò)安全

2010-07-26 11:02:19

Perl模式匹配

2011-09-19 15:40:35

2020-07-29 08:14:59

云計算云遷移IT

2009-07-29 10:36:04

北電收購
點贊
收藏

51CTO技術(shù)棧公眾號