超詳細 WKWebView 開發和使用經驗


轉自:https://developer.51cto.com/article/676860.html

 

 

本文轉載自微信公眾號「網羅開發」,作者兜里有糖同志。轉載本文請聯系網羅開發公眾號。
 
根據需求需要將老項目中的 WebView 替換成 WKWebView,期間查閱了不少文檔和資料,之前也發布了幾篇 WKWebView 相關的優秀文章。
  • WKWebView 幾個不常用的特性
  • WKWebview 加載過程中的性能指標圖解
  • WKWebview 秒開的實踐及踩坑之路

今天分享的這篇文章全面的介紹了 WKWebView,作者根據開發和使用經驗從屬性、方法、代理等方面詳細的做出了總結。

文章較長大家可以先通過目錄了解文章內容。

  • WKWebView 初始化
    • WKWebViewConfiguration
  • 代理方法
    • WKNavigationDelegate
    • WKUIDelegate
  • 屬性和方法
    • 歷史記錄管理
    • WKBackForwardList
    • WKBackForwardListItem
    • 網頁加載
  • WKWebViewConfiguration
    • 進程池 WKProcessPool
    • 偏好設置 WKPreferences
    • 用戶內容控制 WKUserContentController
  • 存儲 WKWebsiteDataStore
    • 內容渲染控制 suppressesIncrementalRendering
    • 追加 User-Agent applicationNameForUserAgent
    • 網頁多媒體播放
    • 選擇粒度 WKSelectionGranularity
    • 數據類型檢測 WKDataDetectorTypes
    • 忽略網頁縮放設置 ignoresViewportScaleLimits
    • 自定義攔截協議 iOS11 以上新支持
  • 代理 WKNavigationDelegate
    • decidePolicyForNavigationAction 首先決定網頁是否繼續訪問
    • iOS13 新增 WKWebpagePreferences
    • decidePolicyForNavigationResponse 是否允許響應回調
    • 當主 Frame 開始加載頁面 didStartProvisionalNavigation
    • 當服務器發起重定向請求 didReceiveServerRedirectForProvisionalNavigation
    • 當容器在加載數據時發生了錯誤 didFailProvisionalNavigation
    • 當容器開始加載數據
    • 當網頁內容開始在主 Frame 開始渲染
    • 在提交主 Frame 導航期間發生了錯誤
    • 當接受 HTTPS 請求證書后執行
    • 當容器內容發生崩潰
  • UI代理 WKUIDelegate
    • 打開新的 WebView createWebViewWithConfiguration
    • 關閉網頁 webViewDidClose
    • 提示信息 runJavaScriptAlertPanelWithMessage
    • 確認信息提示框 runJavaScriptConfirmPanelWithMessage
    • 輸入提示框 runJavaScriptTextInputPanelWithPrompt
    • iOS 13 新增方法 contextMenu 的處理方法
    • FAQ

WKWebView 初始化

WKWebViewConfiguration

WKWebView 如果需要個性化配置,則應該使用以下方法進行初始化。

- (instancetype)initWithFrame:(CGRect)frame  
   configuration:(WKWebViewConfiguration *)configuration NS_DESIGNATED_INITIALIZER; 
  • 1.
  • 2.

示例代碼:

WKWebViewConfiguration *conf = [WKWebViewConfiguration new]; 
WKWebView *wk = [[WKWebView alloc] initWithFrame:CGRectZero configuration:conf]; 
  • 1.
  • 2.

代理方法

WKNavigationDelegate

WKWebView 網頁的導航代理,可以理解為網頁的生命周期事件循環。

WKUIDelegate

WKWebView 網頁的UI交互代理,對於 JS 中的 UI 類型操作需要實現對應的方法,例如 window.alert、window.confirm 等操作。

屬性和方法

歷史記錄管理

WKWebView 系統默認支持對網頁歷史記錄的管理,經過實際測試 302 狀態碼的網頁請求不屬於歷史記錄,200 狀態碼的網頁請求屬於正常的歷史記錄。

WKBackForwardList

支持僅對歷史記錄列表和數據的獲取

WKBackForwardListItem

WKBackForwardListItem 為每一項歷史記錄的數據模型。

/*! @abstract The URL of the webpage represented by this item.   */  @property (readonly, copy) NSURL *URL;      /*! @abstract The title of the webpage represented by this item.   */  @property (nullable, readonly, copy) NSString *title;      /*! @abstract The URL of the initial request that created this item.   */  @property (readonly, copy) NSURL *initialURL;  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

其中 initialURL 和 URL 的區別:

  1. initialURL 為本次網頁加載的初始請求
  2. URL 為本次網頁加載結束后的最終請求
  3. 兩者 URL 區別在於首次發起 302 跳轉的請求
  4. title 為本次網頁加載結束時的 標簽

網頁加載

加載在線地址

正常情況下,一般用 loadRequest 方法加載即可。

- (nullable WKNavigation *)loadRequest:(NSURLRequest *)request; 
  • 1.

loadData 和 loadHTML 也能加載網絡地址,原理都是通過先獲取 NSData 后,利用該方法加載,但是要注意獲取 NSData 的過程是同步,如果網絡請求較慢,會造成主線程阻塞。

NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]]; 
// 直接加載H5數據 
// [wk loadHTMLString:[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] baseURL:nil]; 
[wk loadData:data MIMEType:@"text/html" characterEncodingName:@"UTF-8" baseURL:nil];  
  • 1.
  • 2.
  • 3.
  • 4.

loadHTMLString 和 loadData 中的參數說明:

baseURL:會影響網頁加載過程中 css、js、圖片等資源文件的相對路徑,並不會影響絕對路徑。

MIMEType:為支持加載網頁的類型,有如下類型

文件拓展名 MIMEType
png image/png
bmp/dib image/bmp
jpg/jpeg/jpg image/ipeg
gif image/gif
mp3 audio/mpeg
mp4/mpg4/m4v/mp4v video/mp4
js application/javascript
pdf application/pdf
text/txt text/plain
json application/json
xml text/xml

characterEncodingName:當前返回信息的數據編碼格式:UTF-8、UTF-16、UTF-32、GBK、GB2312等,一般使用 UTF-8。

加載本地地址

Bundle下資源加載

iOS9.0 以上可以使用以下方法加載

- (nullable WKNavigation *)loadFileURL:(NSURL *)URL  
               allowingReadAccessToURL:(NSURL *)readAccessURL API_AVAILABLE(macos(10.11), ios(9.0)); 
  • 1.
  • 2.
  • 其中 readAccessURL 參數不能為空,否則會造成應用崩潰。
  • readAccessURL 參數:允許訪問的資源路徑,如果是在 Bundle 中加載本地 HTML,則需要設置該 HTML 所在的 Bundle 路徑,路徑設置好后,該目錄在 WKWebView 中被視為沙盒目錄,HTML 就可以訪問同級目錄下的資源文件。

Bundle 下示例:

HTML 主地址應為:

YOUR_APP_PATH/WKBundle.bundle/sandbox/index.html

readAccessURL 應為以下兩種:

  • YOUR_APP_PATH/WKBundle.bundle/sandbox
  • YOUR_APP_PATH/WKBundle.bundle/

readAccessURL 的參數為當前 HTML 所在目錄允許訪問,該參數對 Bundle 目錄影響不大,對沙盒目錄影響較大。這個參數不可以設置為:YOUR_APP_PATH/WKBundle.bundle/sandbox/js,否則會造成訪問出錯。

其余訪問本地 HTML 的方法

[wk loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:indexPath]]]; 
  • 1.

同樣,上文中的 loadData 和 loadHTML 也可以訪問本地 html,同樣也存在同步阻塞的問題。

沙盒目錄下資源加載

Docuemnt、Library 和 tmp 目錄

如果本地 HTML 放置在 Docuemnt ,Library 下的話, 則需要將目錄設置為所有靜態資源的最外層。例如目錄結構為:

├─ html-demo 
 | ├─ common 
 |  | ├─ index.css   |  | └─ index.js   | ├─ pages   |  | ├─ relative-common   |  |  | ├─ index.css   |  |  | └─ index.js   |  | └─ index.html  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

如果將 html-demo 目錄放置在 Document、Library 目錄下

  1. 通過 [WKWebView loadFileURL:allowingReadAccessToURL:] 方法可以訪問當前目錄下的相對資源,還需要設置指定訪問 allowingReadAccessToURL 下的資源,注意 allowingReadAccessToURL 需要設置 html 和 css 同時存在的最外層目錄,如上例中,我們將 allowingReadAccessToURL 所需參數設置為 html-demo 目錄的話,這樣既能訪問 common 目錄下的資源,也能訪問 relative-common 下的資源。
  2. 通過 [WKWebView loadRequest:] 方法訪問 index.html 的話,僅能訪問當前頁面所在目錄下的相對路徑資源,無法訪問目錄外的資源,例如上例中,index.html 僅能訪問 relative-common 目錄下的資源,不能訪問 common 目錄下的資源。
  3. 通過 [WKWebView loadData:] 和 [WKWebView loadHTMLString:] 方法僅能加載當前HTML內容,無法加載資源文件,這種加載模式下,由於不需要訪問其他路徑下的資源,屬於單頁渲染和加載,所以效率高。

如果將 html-demo 目錄放置在 tmp 目錄下

  1. 通過 [WKWebView loadRequest:] 方法訪問 index.html 的話,既能訪問 common 下的資源,也能訪問 relative-common 下的資源。
  2. 其余規則同上。

WKWebView 屬性

webView 屬性

  • title: 網頁的標題,一般為 html 中的 中的內容
  • URL: 網頁的URL地址,為最終加載的地址
  • loading: 網頁是否處於加載中,YES 加載中、 NO 加載完成
  • estimatedProgress: 網頁加載進度
  • hasOnlySecureContent: 網頁上的所有資源是否已通過 https 加載
  • serverTrust: 加載 HTTPS 請求服務端所信任的證書

以上屬性都可以采用 KVO 觀察屬性變化:

// NSKeyValueObservingOptionNew 更改后的值 
// NSKeyValueObservingOptionOld 更改前的值 
// NSKeyValueObservingOptionInitial 觀察初始化的值(在注冊觀察服務時會調用一次觸發方法) 
// NSKeyValueObservingOptionPrior 分別在值修改前后觸發方法(即一次修改有兩次觸發) 
[wk addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionInitial context:NULL];  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

注意:添加觀察者模式后,一定要在合適的時機將觀察者模式移除,否則在 iOS10 以下的設備會造成崩潰,原因是 WKWebView 在釋放的時候,扔被強持有觀察者。

  • allowsBackForwardNavigationGestures: 允許手勢交互進行頁面導航跳轉
  • customUserAgent: 自定義 Web 頁面的 UserAgent,會覆蓋容器原有的 User-Agent 請求頭信息
  • allowsLinkPreview: 允許 3Dtouch 預覽頁面,壓力屏存在的情況下

webView 方法

  • canGoBack: 是否可以返回上一頁
  • canGoForward: 是否可以前進一頁
  • goBack: 返回上一頁
  • goForward: 前進一頁
  • eload: 根據當前URL刷新頁面
  • reloadFromOrigin: 根據最初 URL 刷新頁面
  • stopLoading: 停止加載
  • evaluateJavaScript: 執行一段 js 代碼
  • handlesURLScheme:(NSString *)urlScheme: 攔截自定義請求協議,不允許攔截 http,https,ws,wss,ftp
  • takeSnapshotWithConfiguration: 截圖配置只能截取當前一屏畫面

WKWebViewConfiguration

WebView 配置之 WKWebViewConfiguration

進程池 WKProcessPool

WKProcessPool 用於提供給 WKWebView 獲取 Web 內容的進程池,里面包括 cookie 。當一個 WebView初始化,一個新的 Web 內容進程會從一個特殊的進程池中創建,或者一個已存在的進程會被使用。

WKProcessPool 本身沒有任何方法和屬性,通過實現單例進程池后,可以達到 WKWebView 間共享 cookie 的能力,注意:如果在賬戶退出登錄后,單例進程需要釋放。

偏好設置 WKPreferences

WKWebView 的偏好設置,支持以下設置:

  • minimumFontSize: 最小字體設置,默認為 0, H5 中 css 的 “font-size” 的值如果小於該值,則會使用該值作為字體的最小尺寸。
  • javaScriptEnabled: 是否啟用 js 腳本,默認啟用,關閉則不會運算 js 腳本,加快渲染速度。
  • javaScriptCanOpenWindowsAutomatically: 允許使用 js 自動打開 Window,默認不允許,js 在調用 window.open 方法的時候,必須將改值設置為 YES,才能從 WKUIDelegate 的代理方法中獲取到。

用戶內容控制 WKUserContentController

  • 支持注入、移除 js 腳本
  • 支持 Web 內容規則

用戶腳本 WKUserScript

WKUserScript *userScript = [[WKUserScript alloc] initWithSource:@"window.open('https://www.baidu.com')"   injectionTime:(WKUserScriptInjectionTimeAtDocumentStart)   forMainFrameOnly:YES];  
  • 1.
  • 2.
  • 3.

屬性解釋:

  • injectionTime: js 代碼的注入時機,支持 WKUserScriptInjectionTimeAtDocumentStart ,WKUserScriptInjectionTimeAtDocumentEND,分別代表頁面剛渲染前執行,和頁面渲染后執行。
  • forMainFrameOnly: 是否僅注入在主框架,還是包括所有的 iframe 全部注入。

添加用戶腳本 addUserScript

使用 addUserScript 方法來添加 js 腳本。

移除所有用戶腳本 removeAllUserScripts

如果注入時機為在網頁渲染前,那么網頁加載完畢后執行移除腳本操作,則腳本的運算結果並不會受影響,但是在網頁加載完畢前移除腳本的后,腳本將不會執行。

添加腳本消息通道 addScriptMessageHandler

用於 Native 和 js 通信,需要實現 WKScriptMessageHandler 協議。

WKUserContentController *userController = [[WKUserContentController alloc] init]; 
[userController addScriptMessageHandler:self name:@"JSBridge"];  [userController addScriptMessageHandler:self name:@"HWH5"];  conf.userContentController = userController;  JS代碼  window.webkit.messageHandlers.JSBridge.postMessage(...args)  window.webkit.messageHandlers.HWH5.postMessage(...args)  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 可以在任何時機添加,可以添加多個
  • 實現 WKScriptMessageHandler 協議,並實現 didReceiveScriptMessage 方法接受消息,通過 message.name 區分不通的協議
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message 
{ 
    NSLog(@"%@", message.name);  }  
  • 1.
  • 2.
  • 3.
  • 4.

移除腳本消息通道 removeScriptMessageHandlerForName

根據腳本消息通道名稱移除對應的腳本消息通道。可以在任何時機移除,移除后對應的js代碼也會移除。

iOS 11 以上支持內容過濾規則配置

該配置需要結合內容過濾器編譯一起使用,通過對 js 指定的規則編譯后得到一個 WKContentRuleList ,並且通過 userController 添加進 WebView 中。

存儲 WKWebsiteDataStore

以下情況中,WKWebView 在主動發送請求時不會攜帶 cookie。

  • Ajax 請求不會帶上 Response 中 Set-Cookie 的值
  • 302 跳轉不會帶上 Response 中 Set-Cookie 的值

可以使用 iOS11 的新 API 對 WKWebView 進行 cookie 的設置,利用以下代碼對 Cookie 進行持久化設置

NSHTTPCookie *cookie = ....; 
[[WKWebsiteDataStore defaultDataStore].httpCookieStore setCookie:cookie ...]; 
  • 1.
  • 2.
  • 該方法如果在 WKWebView 初始化之前設置,則請求可以立馬帶上 Cookie。

示例代碼:

WKWebViewConfiguration *conf = [WKWebViewConfiguration new]; 
 
// 在初始化方法之前,設置 cookie 
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithPropertie:...]; 
[[WKWebsiteDataStore defaultDataStore].httpCookieStore setCookie:cookie ...]; 
 
WKWebView *wk = [[WKWebView alloc] initWithFrame:CGRectZero configuration:conf]; 
[wk loadRequest:...]; 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 該方法如果在 loadRequest 之前設置 cookie,則請求不會立馬帶上該 Cookie,會在下次請求中攜帶該 cookie。
WKWebViewConfiguration *conf = [WKWebViewConfiguration new]; 
WKWebView *wk = [[WKWebView alloc] initWithFrame:CGRectZero configuration:conf]; 
 
// 在初始化方法之后,設置 cookie 
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithPropertie:...]; 
[[WKWebsiteDataStore defaultDataStore].httpCookieStore setCookie:cookie ...]; 
 
[wk loadRequest:...]; 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

內容渲染控制 suppressesIncrementalRendering

是否等待 H5 內容全部加載完成后才開始渲染畫面,默認為 NO,如果設置為 YES,則 H5 在加載完成之前一直處於白屏狀態。

例如 H5 代碼:

// 在測試H5頁面尾巴處加入如下代碼,可以查看區別。 
<script type="text/javascript">    setTimeout(function(){        for(var i = 1; i<10000; i++)        {            alert(i);        }    })  </script>  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

 

追加 User-Agent applicationNameForUserAgent

不會覆蓋原來的請求頭重 User-Agent 的值屬性,在之后追加自定義的內容。

網頁多媒體播放

allowsAirPlayForMediaPlayback

是否允許 AirPlay 投屏播放,默認允許

mediaTypesRequiringUserActionForPlayback

哪些媒體文件需要強制用戶進行手勢交互后才能播放。

  • WKAudiovisualMediaTypeNone = 0, // 默認無
  • WKAudiovisualMediaTypeAudio = 1 << 0,// 音頻
  • WKAudiovisualMediaTypeVideo = 1 << 1, //視頻
  • WKAudiovisualMediaTypeAll = NSUIntegerMax// 所有

該屬性將影響 H5 中 video 標簽的 autoplay 屬性

allowsInlineMediaPlayback

  • 允許 H5 中的 Video 標簽支持局部視頻播放,不會全屏視頻。
  • 需要配合 Video 標簽的 playinline="true" 屬性,就可以實現局部播放。

allowsPictureInPictureMediaPlayback

A Boolean value indicating whether HTML5 videos may play picture-in-picture.

允許 H5 中 Video 標簽支持畫中畫模式,默認 YES

可以使用 H5 中的 JS 代碼實現畫中畫,video.requestPictureInPicture(),iPhone 不支持,iPad 支持。

選擇粒度 WKSelectionGranularity

用戶可以交互選擇web視圖中的內容的粒度級別.默認是 WKSelectionGranularityDynamic 暫時不知道用於什么場景之下。

數據類型檢測 WKDataDetectorTypes

支持識別 HTML 的中字符信息:

UIDataDetectorTypePhoneNumber // 手機號 
UIDataDetectorTypeLink // 網頁地址 
UIDataDetectorTypeAddress // 郵件地址 
UIDataDetectorTypeCalendarEvent //  格式化為日歷事件的信息 
UIDataDetectorTypeShipmentTrackingNumber // 快遞包裹信息 
UIDataDetectorTypeFlightNumber // 航班號信息 
UIDataDetectorTypeLookupSuggestion // 用戶可能要查找的信息 
UIDataDetectorTypeNone // 默認,不檢測 
UIDataDetectorTypeAll // 識別全部信息 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

默認為 UIDataDetectorTypeNone,開啟檢測會影響網頁渲染速度。

忽略網頁縮放設置 ignoresViewportScaleLimits

ignoresViewportScaleLimits 是否忽略頁面縮放限制,默認為 NO。

  • 如果配置為 YES,當前 Web 頁面可以通過放大手勢進行縮放。

和 H5 中的參數存在關聯:

<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=0.5,user-scalable=yes" />  
  • 1.

 

  • minimum-scale=1
  • maximum-scale=1
  • user-scalable=yes
名稱        
ignoresViewportScaleLimits NO NO YES YES
user-scalable YES NO YES NO
結論 按照指定尺寸進行縮放 無法進行縮放 任意放大 任意放大

自定義攔截協議 iOS11 以上新支持

- (void)setURLSchemeHandler:(nullable id <WKURLSchemeHandler>)urlSchemeHandler  
 forURLScheme:(NSString *)urlScheme API_AVAILABLE(macos(10.13), ios(11.0)); 
 
- (nullable id <WKURLSchemeHandler>)urlSchemeHandlerForURLScheme:(NSString *)urlScheme API_AVAILABLE(macos(10.13), ios(11.0)); 
  • 1.
  • 2.
  • 3.
  • 4.

我們可以通過上述方法對 WKWebView 進行自定義協議攔截,無法攔截 http、https、ws、wss、ftp 協議。

示例代碼:

[conf setURLSchemeHandler:[ViewSchemaHandler new] forURLScheme:@"h5"];  
  • 1.

在 ViewSchemaHandler 實現協議中的內容

- (void)webView:(WKWebView *)webView startURLSchemeTask:(id<WKURLSchemeTask>)urlSchemeTask 
{ 
    // 在這里可以對同一資源進行本地緩存,無需要再次訪問。 
    NSMutableURLRequest *request = urlSchemeTask.request.mutableCopy; 
    request.URL = [NSURL URLWithString:[request.URL.absoluteString stringByReplacingOccurrencesOfString:@"h5://" withString:@"http://"]];      NSLog(@"%@", request.URL.absoluteURL);      NSURLSession* session = [NSURLSession sharedSession];      NSURLSessionTask* task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {          [urlSchemeTask didReceiveResponse:response];          [urlSchemeTask didReceiveData:data];          [urlSchemeTask didFinish];      }];      [task resume];  }  - (void)webView:(WKWebView *)webView stopURLSchemeTask:(id<WKURLSchemeTask>)urlSchemeTask  {     // 當前urlSchemeTask由於某些原因提前結束了(會收到stopURLSchemeTask回調)  }  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

注意:

  • 在 H5 前端所有想要攔截的 js,css 或者其他網絡請求資源,需要將路徑寫成自適應協議路徑,例如如下寫法即可:
<script type="text/javascript" src="//192.168.1.150:3206/7.3.7/js/libs/jquery.min.js" ></script>  
  • 1.
  • 在 H5 前端所有想要攔截的 Ajax 請求,需要將請求更改為相對或者絕對路徑,即可實現攔截
$.ajax({ 
 url:"/abcd"  });  
  • 1.
  • 2.
  • 3.

可以利用上述特性實現應用秒開。

代理 WKNavigationDelegate

decidePolicyForNavigationAction 首先決定網頁是否繼續訪問

可以通過 decidePolicyForNavigationAction 中的 decisionHandler 回調方法進行回調。

WKNavigationActionPolicyCancel 取消訪問 WKNavigationActionPolicyAllow 允許繼續訪問,如果不實現該代理方法,則默認允許訪問

示例代碼:

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler 
{ 
  // decisionHandler(WKNavigationActionPolicyCancel); 
    decisionHandler(WKNavigationActionPolicyAllow); 
} 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

iOS13 新增 WKWebpagePreferences

支持偏好設置,暫不理解。

decidePolicyForNavigationResponse 是否允許響應回調

是否允許響應回調,操作同 decidePolicyForNavigationAction 一致。

當主 Frame 開始加載頁面 didStartProvisionalNavigation

didStartProvisionalNavigation 發起首次請求會執行這個方法,多次 302 重定向請求,該方法只會執行一次,發生 多次 302 跳轉的時候,每次都會先執行 decidePolicyForNavigationAction ,如果這時候用戶選擇 cancel 操作,則 didReceiveServerRedirectForProvisionalNavigation 方法不會執行。

當服務器發起重定向請求 didReceiveServerRedirectForProvisionalNavigation

didReceiveServerRedirectForProvisionalNavigation,發生 302 重定向會走該方法

當容器在加載數據時發生了錯誤 didFailProvisionalNavigation

正常加載地址或者使用 js 中的 location.href 加載錯誤的地址發生失敗會走該回調。

[WKWebView loadRequest:] // 發生失敗會走該回調 
// js代碼 
location.href="http://abcd" // 發生失敗會走該回調  
  • 1.
  • 2.
  • 3.

當容器開始加載數據

didCommitNavigation,網絡請求加載完成后執行。

當網頁內容開始在主 Frame 開始渲染

didFinishNavigation 完成 js,css,html 渲染后執行。

在提交主 Frame 導航期間發生了錯誤

didFailNavigation,例如:

window.open("http://abcd") // 發生失敗后會走該回調  
  • 1.

當接受 HTTPS 請求證書后執行

didReceiveAuthenticationChallenge,可以通過 completionHandler 來選擇對證書的操作,例如忽略證書。

/* 
NSURLSessionAuthChallengeUseCredential = 0,                 使用證書 
NSURLSessionAuthChallengePerformDefaultHandling = 1,   忽略證書(默認的處理方式) 
NSURLSessionAuthChallengeCancelAuthenticationChallenge = 2,     忽略書證, 並取消這次請求 
NSURLSessionAuthChallengeRejectProtectionSpace = 3,            拒絕當前這一次, 下一次再詢問 
*/ 
// NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; 
 
NSURLCredential *card = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust]; 
 completionHandler(NSURLSessionAuthChallengeUseCredential , card); 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

當容器內容發生崩潰

webViewWebContentProcessDidTerminate,webView 內容發生崩潰而終止,將會執行該回調方法。

UI代理 WKUIDelegate

UI 代理方法,是 H5 部分 UI 操作和原生交互的代理方法,其中包括如下:

打開新的 WebView createWebViewWithConfiguration

H5 中需要打開新窗口的操作,都會被這個方法攔截,例如

<a href="https://www.baidu.com" target="_blank" >打開新窗口</a>  window.open("https://www.baidu.com");  
  • 1.
  • 2.

關閉網頁 webViewDidClose

當 H5 執行 window.close() 方法,則會執行這個代理方法。

提示信息 runJavaScriptAlertPanelWithMessage

當 H5 執行 window.alert(...args) 方法,則會執行這個代理方法,需要注意:

completionHandler 這個 block 方法必須執行,否則會發生崩潰,彈出窗口如果使用 UIAlertController 作為對接,則要考慮控制器是否存在,是否有並發的彈出窗操作,因為這些會導致 UIAlertController彈不出來,最終可能在邏輯上造成 completionHandler 無法執行導致崩潰,最好建議彈窗應該使用 UIView 設計。

確認信息提示框 runJavaScriptConfirmPanelWithMessage

當 H5 執行 window.confirm(...args),則會執行這個代理方法,注意事項同上。

輸入提示框 runJavaScriptTextInputPanelWithPrompt

當H5執行 window.prompt(...args),則會執行這個代理方法,注意事項同上。

iOS 13 新增方法 contextMenu 的處理方法

contextMenu 的相關處理方法,暫時不理解在手機端有何用處。

FAQ

  • WKWebView 中 H5 css 動畫失效的問題?

目前測試下來

  • [UIView snapshotViewAfterScreenUpdates:YES];
  • [UIView drawViewHierarchyInRect:CGRect afterScreenUpdates:YES];

這兩種方法在進行系統 UIView 的截圖操作時候並且將參數 afterScreenUpdates 設置為 YES 的情況下,最后 頻繁調用后會導致 H5 中 css 動畫失效,原因不明。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM