當前位置:成語大全網 - 新華字典 - [iOS]使用WKWebView遇到的問題總結

[iOS]使用WKWebView遇到的問題總結

在使用WKWebView獲取userAgent的時候, 如果要全局配置, 使所有的WKWebView都能生效, 我們可能的做法是在AppDelegate中來配置, 但是需要壹個WKWebView實例對象, 所以可能是這麽寫的:

這樣, 妳會發現設置壹直是無效的, 在回調裏打印壹下:

這時發現獲取到的 info 字段為nil, 並且error信息如下:

個人猜測: 這是因為, WKWebView的evaluateJavaScript方法是異步執行的, 當WKWebView回調這個方法的時候, 其實例對象已經從內存中釋放了, 所以導致回調出錯.

我做了如下驗證, 在回調方法裏輸出webView實例對象:

會發現輸出是info有值, 而error為nil, webView有值, 又正常了, 有人說了,看樣子不是這個問題! 真的麽? 仔細想壹下會發現, 在webView的方法回調閉包裏使用了webView實例, 會發生什麽? 對, 循環引用! webView實例此時不為nil, 這也驗證了, 如果webView實例正常的話, 獲取結果是不會有誤的! 繼續上面的驗證, 我們弱引用壹下:

這時, 會發現: info和webView都為nil, error值為上面那個錯誤!!!

這樣, 基本驗證出現這個問題的原因是: webView 提前釋放了!

但是為了添加這個設置, 而將webView 設為全局變量, 仿佛有點得不償失, 這時可以在使用webView的頁面進行設置, 或者使用UIWebView替換:

在做JS與原生交互的時候, 使用下面方法註入的協議無效:

然後在js端使用的時候: 這裏不需要傳參數, 直接這麽寫的

這樣, 沒有響應js端的事件!!!

在代理方法中:

壹直沒有收到回調!!!

其實, 並不是註入協議失敗, 這麽使用也沒問題, 問題就出在postMessage的參數上, 如果是帶參數的:

這麽寫, 是完全沒有問題的, 所以如果不需傳參數的話, 可以這麽寫:

給壹個空的字典, 就能正常交互了!!!

在WKWebView加載的HTML頁面上, 如果長按會彈出壹些選擇框, 在文字上長按, 會彈出UIMenuController選擇框:

而在圖片上長按, 會彈出壹個alertSheet:

這裏可以保存圖片到系統相冊(如果有權限), 或者復制到剪切板. 但是這些需求並不是我們需要, 如何禁止這些行為呢?需要從JS入手, 只需要執行下面兩句js即可:

可以在創建WKWebView的時候註入:

也可以在頁面加載完成後的代理方法中執行:

在加載的HTML頁面中, 無端出現壹個廣告的懸浮框:

打開之後是這樣的:

而且只會在移動4G網絡下才會出現, 其實這是移動的流量劫持, 強加的廣告推廣,目前網上有壹些解決方式,常用的有:

其他的可參考這篇文章 iOS 客戶端對於運營商劫持的壹點點對抗方式

在聯調的時候, 前端的同學改了壹些東西, 例如頁面的布局, 顯示元素, 或者js方法, 而APP端沒反應!!!

這是因為, WKWebView有緩存, 為了保證每次加載的都是最新的頁面, 可以在加載的鏈接後面加上壹個時間戳, 例如妳的HTML地址為:

壹般使用是這樣的:

這樣的話是有緩存, 加載壹次之後, 再去加載也不是最新的頁面, 可以這樣使用:

這樣每次加載的時候都會是最新的, 當然弊端就是, 每次都會耗費壹些額外的流量.

在頁面無導航的情況下,系統會自動調節滾動視圖的contentInset,使其視圖永遠處於狀態欄之下,但是如果我們想讓滾動視圖的Y坐標從屏幕頂端(狀態欄)開始,我們都知道怎麽修改,但是 WKWebView不是繼承自UIScrollView 的,所以不能直接設置,可以這麽寫:

這個閃退發生在與 JS 進行交互,使用下面的方法註冊協議時:

如果重復註冊了相同名稱的協議,就會發生閃退,所以在使用完webView的時候,壹定要記得移除已註冊的協議:

app首頁使用 WKWebView 來承載的內容,在啟動時,如果添加了引導頁/廣告頁,這時如果有手勢操作,例如在出現廣告頁時點擊屏幕,就會閃退,並在控制臺輸出:

添加壹個全局斷點,調試發現崩潰信息為

查了些資料,沒找到具體原因,但是了解到和 +load方法有關,我是在 +load 方法內初始化的廣告頁的信息,把這些放在 didFinishLaunchingWithOptions 進行初始化,就不會有這個問題;

解決:

將廣告/引導頁視圖的初始化放在 didFinishLaunchingWithOptions 方法內。