1. 程式人生 > 其它 >WKWebView 白屏問題,WKWebView request body丟失問題

WKWebView 白屏問題,WKWebView request body丟失問題

WKWebView 白屏

1,WKWebView 白屏問題
WKWebView 自詡擁有更快的載入速度,更低的記憶體佔用,但實際上 WKWebView 是一個多程序元件,Network Loading 以及 UI Rendering 在其它程序中執行。初次適配 WKWebView 的時候,我們也驚訝於開啟 WKWebView 後,App 程序記憶體消耗反而大幅下降,但是仔細觀察會發現,Other Process 的記憶體佔用會增加。在一些用 webGL 渲染的複雜頁面,使用 WKWebView 總體的記憶體佔用(App Process Memory + Other Process Memory)不見得比 UIWebView 少很多。
在 UIWebView 上當記憶體佔用太大的時候,App Process 會 crash;而在 WKWebView 上當總體的記憶體佔用比較大的時候,WebContent Process 會 crash,從而出現白屏現象。

解決方案:

- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView API_AVAILABLE(macosx(10.11), ios(9.0));

當 WKWebView 總體記憶體佔用過大,頁面即將白屏的時候,系統會呼叫上面的回撥函式代理方法,我們在該函式裡執行[webView reload](這個時候 webView.URL 取值尚不為 nil)解決白屏問題。在一些高記憶體消耗的頁面可能會頻繁重新整理當前頁面,H5側也要做相應的適配操作。

2、WKWebView loadRequest 問題

WKWebView 通過loadrequest方法載入Post請求會丟失請求體(body)中的內容,進而導致伺服器拿不到body中的內容的問題的發生。這個問題的產生主要是因為WKWebView的網路請求的程序與APP不是同一個程序,所以網路請求的過程是這樣的:

由APP所在的程序發起request,然後通過IPC通訊(程序間通訊)將請求的相關資訊(請求頭、請求行、請求體等)傳遞給webkit網路線程序接收包裝,進行資料的HTTP請求,最終再進行IPC的通訊回傳給APP所在的程序的。這裡如果發起的request請求是post請求的話,由於要進行IPC資料傳遞,傳遞的請求體body中根據系統排程,將其捨棄,最終在WKWebView網路程序接受的時候請求體body中的內容變成了空,導致此種情況下的伺服器獲取不到請求體,導致問題的產生。

解決問題:

1.將網路請求交由Js發起,繞開系統WKWebView的網路的程序請求達到正常請求的目的

2.改變POST請求的方法為GET方法(有風險,不一定伺服器會接受GET方法)

3.將Post請求的請求body內容放入請求的Header中,並通過URLProtocol攔截自定義協議,在攔截中通過NSConnection進行重新請求(重新包裝請求body),然後通過回撥Client客戶端來傳遞資料內容

3,WKWebView 頁面樣式問題
在 WKWebView 適配過程中,發現部分H5頁面元素位置向下偏移或被拉伸變形,追蹤後發現主要是H5頁面高度值異常導致:
解決方案:
調整WKWebView佈局方式,避免調整webView.scrollView.contentInset。實際上,即便在 UIWebView 上也不建議直接調整webView.scrollView.contentInset的值,這確實會帶來一些奇怪的問題。如果某些特殊情況下非得調整 contentInset 不可的話,可以通過下面方式讓H5頁面恢復正常顯示:

/**設定contentInset值後通過調整webView.frame讓頁面恢復正常顯示 *參考:http://km.oa.com/articles/show/277372 */

webView.scrollView.contentInset = UIEdgeInsetsMake(a, 0, 0, 0); 

webView.frame = CGRectMake(webView.frame.origin.x, webView.frame.origin.y, webView.frame.size.width, webView.frame.size.height - a);

4,視訊自動播放
WKWebView 需要通過WKWebViewConfiguration.mediaPlaybackRequiresUserAction設定是否允許自動播放,但一定要在 WKWebView 初始化之前設定,在 WKWebView 初始化之後設定無效。