自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

超詳細(xì) WKWebView 開(kāi)發(fā)和使用經(jīng)驗(yàn)

開(kāi)發(fā) 前端
今天分享的這篇文章全面的介紹了 WKWebView,作者根據(jù)開(kāi)發(fā)和使用經(jīng)驗(yàn)從屬性、方法、代理等方面詳細(xì)的做出了總結(jié)。
本文轉(zhuǎn)載自微信公眾號(hào)「網(wǎng)羅開(kāi)發(fā)」,作者兜里有糖同志。轉(zhuǎn)載本文請(qǐng)聯(lián)系網(wǎng)羅開(kāi)發(fā)公眾號(hào)。
 
根據(jù)需求需要將老項(xiàng)目中的 WebView 替換成 WKWebView,期間查閱了不少文檔和資料,之前也發(fā)布了幾篇 WKWebView 相關(guān)的優(yōu)秀文章。
  • WKWebView 幾個(gè)不常用的特性
  • WKWebview 加載過(guò)程中的性能指標(biāo)圖解
  • WKWebview 秒開(kāi)的實(shí)踐及踩坑之路

今天分享的這篇文章全面的介紹了 WKWebView,作者根據(jù)開(kāi)發(fā)和使用經(jīng)驗(yàn)從屬性、方法、代理等方面詳細(xì)的做出了總結(jié)。

文章較長(zhǎng)大家可以先通過(guò)目錄了解文章內(nèi)容。

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

WKWebView 初始化

WKWebViewConfiguration

WKWebView 如果需要個(gè)性化配置,則應(yīng)該使用以下方法進(jìn)行初始化。

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

示例代碼:

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

代理方法

WKNavigationDelegate

WKWebView 網(wǎng)頁(yè)的導(dǎo)航代理,可以理解為網(wǎng)頁(yè)的生命周期事件循環(huán)。

WKUIDelegate

WKWebView 網(wǎng)頁(yè)的UI交互代理,對(duì)于 JS 中的 UI 類型操作需要實(shí)現(xiàn)對(duì)應(yīng)的方法,例如 window.alert、window.confirm 等操作。

屬性和方法

歷史記錄管理

WKWebView 系統(tǒng)默認(rèn)支持對(duì)網(wǎng)頁(yè)歷史記錄的管理,經(jīng)過(guò)實(shí)際測(cè)試 302 狀態(tài)碼的網(wǎng)頁(yè)請(qǐng)求不屬于歷史記錄,200 狀態(tài)碼的網(wǎng)頁(yè)請(qǐng)求屬于正常的歷史記錄。

WKBackForwardList

支持僅對(duì)歷史記錄列表和數(shù)據(jù)的獲取

WKBackForwardListItem

WKBackForwardListItem 為每一項(xiàng)歷史記錄的數(shù)據(jù)模型。

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

其中 initialURL 和 URL 的區(qū)別:

  1. initialURL 為本次網(wǎng)頁(yè)加載的初始請(qǐng)求
  2. URL 為本次網(wǎng)頁(yè)加載結(jié)束后的最終請(qǐng)求
  3. 兩者 URL 區(qū)別在于首次發(fā)起 302 跳轉(zhuǎn)的請(qǐng)求
  4. title 為本次網(wǎng)頁(yè)加載結(jié)束時(shí)的 標(biāo)簽

網(wǎng)頁(yè)加載

加載在線地址

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

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

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

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

loadHTMLString 和 loadData 中的參數(shù)說(shuō)明:

baseURL:會(huì)影響網(wǎng)頁(yè)加載過(guò)程中 css、js、圖片等資源文件的相對(duì)路徑,并不會(huì)影響絕對(duì)路徑。

MIMEType:為支持加載網(wǎng)頁(yè)的類型,有如下類型

文件拓展名 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:當(dāng)前返回信息的數(shù)據(jù)編碼格式:UTF-8、UTF-16、UTF-32、GBK、GB2312等,一般使用 UTF-8。

加載本地地址

Bundle下資源加載

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

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

Bundle 下示例:

HTML 主地址應(yīng)為:

YOUR_APP_PATH/WKBundle.bundle/sandbox/index.html

readAccessURL 應(yīng)為以下兩種:

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

readAccessURL 的參數(shù)為當(dāng)前 HTML 所在目錄允許訪問(wèn),該參數(shù)對(duì) Bundle 目錄影響不大,對(duì)沙盒目錄影響較大。這個(gè)參數(shù)不可以設(shè)置為:YOUR_APP_PATH/WKBundle.bundle/sandbox/js,否則會(huì)造成訪問(wèn)出錯(cuò)。

其余訪問(wèn)本地 HTML 的方法

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

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

沙盒目錄下資源加載

Docuemnt、Library 和 tmp 目錄

如果本地 HTML 放置在 Docuemnt ,Library 下的話, 則需要將目錄設(shè)置為所有靜態(tài)資源的最外層。例如目錄結(jié)構(gòu)為:

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

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

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

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

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

WKWebView 屬性

webView 屬性

  • title: 網(wǎng)頁(yè)的標(biāo)題,一般為 html 中的 中的內(nèi)容
  • URL: 網(wǎng)頁(yè)的URL地址,為最終加載的地址
  • loading: 網(wǎng)頁(yè)是否處于加載中,YES 加載中、 NO 加載完成
  • estimatedProgress: 網(wǎng)頁(yè)加載進(jìn)度
  • hasOnlySecureContent: 網(wǎng)頁(yè)上的所有資源是否已通過(guò) https 加載
  • serverTrust: 加載 HTTPS 請(qǐng)求服務(wù)端所信任的證書(shū)

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

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

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

  • allowsBackForwardNavigationGestures: 允許手勢(shì)交互進(jìn)行頁(yè)面導(dǎo)航跳轉(zhuǎn)
  • customUserAgent: 自定義 Web 頁(yè)面的 UserAgent,會(huì)覆蓋容器原有的 User-Agent 請(qǐng)求頭信息
  • allowsLinkPreview: 允許 3Dtouch 預(yù)覽頁(yè)面,壓力屏存在的情況下

webView 方法

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

WKWebViewConfiguration

WebView 配置之 WKWebViewConfiguration

進(jìn)程池 WKProcessPool

WKProcessPool 用于提供給 WKWebView 獲取 Web 內(nèi)容的進(jìn)程池,里面包括 cookie 。當(dāng)一個(gè) WebView初始化,一個(gè)新的 Web 內(nèi)容進(jìn)程會(huì)從一個(gè)特殊的進(jìn)程池中創(chuàng)建,或者一個(gè)已存在的進(jìn)程會(huì)被使用。

WKProcessPool 本身沒(méi)有任何方法和屬性,通過(guò)實(shí)現(xiàn)單例進(jìn)程池后,可以達(dá)到 WKWebView 間共享 cookie 的能力,注意:如果在賬戶退出登錄后,單例進(jìn)程需要釋放。

偏好設(shè)置 WKPreferences

WKWebView 的偏好設(shè)置,支持以下設(shè)置:

  • minimumFontSize: 最小字體設(shè)置,默認(rèn)為 0, H5 中 css 的 “font-size” 的值如果小于該值,則會(huì)使用該值作為字體的最小尺寸。
  • javaScriptEnabled: 是否啟用 js 腳本,默認(rèn)啟用,關(guān)閉則不會(huì)運(yùn)算 js 腳本,加快渲染速度。
  • javaScriptCanOpenWindowsAutomatically: 允許使用 js 自動(dòng)打開(kāi) Window,默認(rèn)不允許,js 在調(diào)用 window.open 方法的時(shí)候,必須將改值設(shè)置為 YES,才能從 WKUIDelegate 的代理方法中獲取到。

用戶內(nèi)容控制 WKUserContentController

  • 支持注入、移除 js 腳本
  • 支持 Web 內(nèi)容規(guī)則

用戶腳本 WKUserScript

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

屬性解釋:

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

添加用戶腳本 addUserScript

使用 addUserScript 方法來(lái)添加 js 腳本。

移除所有用戶腳本 removeAllUserScripts

如果注入時(shí)機(jī)為在網(wǎng)頁(yè)渲染前,那么網(wǎng)頁(yè)加載完畢后執(zhí)行移除腳本操作,則腳本的運(yùn)算結(jié)果并不會(huì)受影響,但是在網(wǎng)頁(yè)加載完畢前移除腳本的后,腳本將不會(huì)執(zhí)行。

添加腳本消息通道 addScriptMessageHandler

用于 Native 和 js 通信,需要實(shí)現(xiàn) WKScriptMessageHandler 協(xié)議。

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

移除腳本消息通道 removeScriptMessageHandlerForName

根據(jù)腳本消息通道名稱移除對(duì)應(yīng)的腳本消息通道??梢栽谌魏螘r(shí)機(jī)移除,移除后對(duì)應(yīng)的js代碼也會(huì)移除。

iOS 11 以上支持內(nèi)容過(guò)濾規(guī)則配置

該配置需要結(jié)合內(nèi)容過(guò)濾器編譯一起使用,通過(guò)對(duì) js 指定的規(guī)則編譯后得到一個(gè) WKContentRuleList ,并且通過(guò) userController 添加進(jìn) WebView 中。

存儲(chǔ) WKWebsiteDataStore

以下情況中,WKWebView 在主動(dòng)發(fā)送請(qǐng)求時(shí)不會(huì)攜帶 cookie。

  • Ajax 請(qǐng)求不會(huì)帶上 Response 中 Set-Cookie 的值
  • 302 跳轉(zhuǎn)不會(huì)帶上 Response 中 Set-Cookie 的值

可以使用 iOS11 的新 API 對(duì) WKWebView 進(jìn)行 cookie 的設(shè)置,利用以下代碼對(duì) Cookie 進(jìn)行持久化設(shè)置

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

示例代碼:

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

內(nèi)容渲染控制 suppressesIncrementalRendering

是否等待 H5 內(nèi)容全部加載完成后才開(kāi)始渲染畫(huà)面,默認(rèn)為 NO,如果設(shè)置為 YES,則 H5 在加載完成之前一直處于白屏狀態(tài)。

例如 H5 代碼:

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

 

追加 User-Agent applicationNameForUserAgent

不會(huì)覆蓋原來(lái)的請(qǐng)求頭重 User-Agent 的值屬性,在之后追加自定義的內(nèi)容。

網(wǎng)頁(yè)多媒體播放

allowsAirPlayForMediaPlayback

是否允許 AirPlay 投屏播放,默認(rèn)允許

mediaTypesRequiringUserActionForPlayback

哪些媒體文件需要強(qiáng)制用戶進(jìn)行手勢(shì)交互后才能播放。

  • WKAudiovisualMediaTypeNone = 0, // 默認(rèn)無(wú)
  • WKAudiovisualMediaTypeAudio = 1 << 0,// 音頻
  • WKAudiovisualMediaTypeVideo = 1 << 1, //視頻
  • WKAudiovisualMediaTypeAll = NSUIntegerMax// 所有

該屬性將影響 H5 中 video 標(biāo)簽的 autoplay 屬性

allowsInlineMediaPlayback

  • 允許 H5 中的 Video 標(biāo)簽支持局部視頻播放,不會(huì)全屏視頻。
  • 需要配合 Video 標(biāo)簽的 playinline="true" 屬性,就可以實(shí)現(xiàn)局部播放。

allowsPictureInPictureMediaPlayback

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

允許 H5 中 Video 標(biāo)簽支持畫(huà)中畫(huà)模式,默認(rèn) YES

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

[[415927]]

選擇粒度 WKSelectionGranularity

用戶可以交互選擇web視圖中的內(nèi)容的粒度級(jí)別.默認(rèn)是 WKSelectionGranularityDynamic 暫時(shí)不知道用于什么場(chǎng)景之下。

數(shù)據(jù)類型檢測(cè) WKDataDetectorTypes

支持識(shí)別 HTML 的中字符信息:

  1. UIDataDetectorTypePhoneNumber // 手機(jī)號(hào) 
  2. UIDataDetectorTypeLink // 網(wǎng)頁(yè)地址 
  3. UIDataDetectorTypeAddress // 郵件地址 
  4. UIDataDetectorTypeCalendarEvent //  格式化為日歷事件的信息 
  5. UIDataDetectorTypeShipmentTrackingNumber // 快遞包裹信息 
  6. UIDataDetectorTypeFlightNumber // 航班號(hào)信息 
  7. UIDataDetectorTypeLookupSuggestion // 用戶可能要查找的信息 
  8. UIDataDetectorTypeNone // 默認(rèn),不檢測(cè) 
  9. UIDataDetectorTypeAll // 識(shí)別全部信息 

默認(rèn)為 UIDataDetectorTypeNone,開(kāi)啟檢測(cè)會(huì)影響網(wǎng)頁(yè)渲染速度。

忽略網(wǎng)頁(yè)縮放設(shè)置 ignoresViewportScaleLimits

ignoresViewportScaleLimits 是否忽略頁(yè)面縮放限制,默認(rèn)為 NO。

  • 如果配置為 YES,當(dāng)前 Web 頁(yè)面可以通過(guò)放大手勢(shì)進(jìn)行縮放。

和 H5 中的參數(shù)存在關(guān)聯(lián):

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

 

  • minimum-scale=1
  • maximum-scale=1
  • user-scalable=yes
名稱        
ignoresViewportScaleLimits NO NO YES YES
user-scalable YES NO YES NO
結(jié)論 按照指定尺寸進(jìn)行縮放 無(wú)法進(jìn)行縮放 任意放大 任意放大

自定義攔截協(xié)議 iOS11 以上新支持

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

我們可以通過(guò)上述方法對(duì) WKWebView 進(jìn)行自定義協(xié)議攔截,無(wú)法攔截 http、https、ws、wss、ftp 協(xié)議。

示例代碼:

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

在 ViewSchemaHandler 實(shí)現(xiàn)協(xié)議中的內(nèi)容

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

注意:

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

可以利用上述特性實(shí)現(xiàn)應(yīng)用秒開(kāi)。

代理 WKNavigationDelegate

decidePolicyForNavigationAction 首先決定網(wǎng)頁(yè)是否繼續(xù)訪問(wèn)

可以通過(guò) decidePolicyForNavigationAction 中的 decisionHandler 回調(diào)方法進(jìn)行回調(diào)。

WKNavigationActionPolicyCancel 取消訪問(wèn) WKNavigationActionPolicyAllow 允許繼續(xù)訪問(wèn),如果不實(shí)現(xiàn)該代理方法,則默認(rèn)允許訪問(wèn)

示例代碼:

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

iOS13 新增 WKWebpagePreferences

支持偏好設(shè)置,暫不理解。

decidePolicyForNavigationResponse 是否允許響應(yīng)回調(diào)

是否允許響應(yīng)回調(diào),操作同 decidePolicyForNavigationAction 一致。

當(dāng)主 Frame 開(kāi)始加載頁(yè)面 didStartProvisionalNavigation

didStartProvisionalNavigation 發(fā)起首次請(qǐng)求會(huì)執(zhí)行這個(gè)方法,多次 302 重定向請(qǐng)求,該方法只會(huì)執(zhí)行一次,發(fā)生 多次 302 跳轉(zhuǎn)的時(shí)候,每次都會(huì)先執(zhí)行 decidePolicyForNavigationAction ,如果這時(shí)候用戶選擇 cancel 操作,則 didReceiveServerRedirectForProvisionalNavigation 方法不會(huì)執(zhí)行。

當(dāng)服務(wù)器發(fā)起重定向請(qǐng)求 didReceiveServerRedirectForProvisionalNavigation

didReceiveServerRedirectForProvisionalNavigation,發(fā)生 302 重定向會(huì)走該方法

當(dāng)容器在加載數(shù)據(jù)時(shí)發(fā)生了錯(cuò)誤 didFailProvisionalNavigation

正常加載地址或者使用 js 中的 location.href 加載錯(cuò)誤的地址發(fā)生失敗會(huì)走該回調(diào)。

  1. [WKWebView loadRequest:] // 發(fā)生失敗會(huì)走該回調(diào) 
  2. // js代碼 
  3. location.href="http://abcd" // 發(fā)生失敗會(huì)走該回調(diào) 

當(dāng)容器開(kāi)始加載數(shù)據(jù)

didCommitNavigation,網(wǎng)絡(luò)請(qǐng)求加載完成后執(zhí)行。

當(dāng)網(wǎng)頁(yè)內(nèi)容開(kāi)始在主 Frame 開(kāi)始渲染

didFinishNavigation 完成 js,css,html 渲染后執(zhí)行。

在提交主 Frame 導(dǎo)航期間發(fā)生了錯(cuò)誤

didFailNavigation,例如:

  1. window.open("http://abcd") // 發(fā)生失敗后會(huì)走該回調(diào) 

當(dāng)接受 HTTPS 請(qǐng)求證書(shū)后執(zhí)行

didReceiveAuthenticationChallenge,可以通過(guò) completionHandler 來(lái)選擇對(duì)證書(shū)的操作,例如忽略證書(shū)。

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

當(dāng)容器內(nèi)容發(fā)生崩潰

webViewWebContentProcessDidTerminate,webView 內(nèi)容發(fā)生崩潰而終止,將會(huì)執(zhí)行該回調(diào)方法。

UI代理 WKUIDelegate

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

打開(kāi)新的 WebView createWebViewWithConfiguration

H5 中需要打開(kāi)新窗口的操作,都會(huì)被這個(gè)方法攔截,例如

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

關(guān)閉網(wǎng)頁(yè) webViewDidClose

當(dāng) H5 執(zhí)行 window.close() 方法,則會(huì)執(zhí)行這個(gè)代理方法。

提示信息 runJavaScriptAlertPanelWithMessage

當(dāng) H5 執(zhí)行 window.alert(...args) 方法,則會(huì)執(zhí)行這個(gè)代理方法,需要注意:

completionHandler 這個(gè) block 方法必須執(zhí)行,否則會(huì)發(fā)生崩潰,彈出窗口如果使用 UIAlertController 作為對(duì)接,則要考慮控制器是否存在,是否有并發(fā)的彈出窗操作,因?yàn)檫@些會(huì)導(dǎo)致 UIAlertController彈不出來(lái),最終可能在邏輯上造成 completionHandler 無(wú)法執(zhí)行導(dǎo)致崩潰,最好建議彈窗應(yīng)該使用 UIView 設(shè)計(jì)。

確認(rèn)信息提示框 runJavaScriptConfirmPanelWithMessage

當(dāng) H5 執(zhí)行 window.confirm(...args),則會(huì)執(zhí)行這個(gè)代理方法,注意事項(xiàng)同上。

輸入提示框 runJavaScriptTextInputPanelWithPrompt

當(dāng)H5執(zhí)行 window.prompt(...args),則會(huì)執(zhí)行這個(gè)代理方法,注意事項(xiàng)同上。

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

contextMenu 的相關(guān)處理方法,暫時(shí)不理解在手機(jī)端有何用處。

FAQ

  • WKWebView 中 H5 css 動(dòng)畫(huà)失效的問(wèn)題?

目前測(cè)試下來(lái)

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

這兩種方法在進(jìn)行系統(tǒng) UIView 的截圖操作時(shí)候并且將參數(shù) afterScreenUpdates 設(shè)置為 YES 的情況下,最后 頻繁調(diào)用后會(huì)導(dǎo)致 H5 中 css 動(dòng)畫(huà)失效,原因不明。

 

責(zé)任編輯:武曉燕 來(lái)源: 網(wǎng)羅開(kāi)發(fā)
相關(guān)推薦

2022-06-26 09:56:50

HttpUtil工具類模式

2019-12-31 20:55:13

Socket通信TCP

2018-10-15 10:15:30

STM32Linux經(jīng)驗(yàn)

2011-09-14 09:30:27

2023-10-09 07:57:14

JavaJCF

2011-08-19 13:34:33

iPhone應(yīng)用ABAddressBo

2010-01-07 17:00:38

VB.NET控件數(shù)組

2022-11-10 07:38:56

Javaagent類隔離

2009-08-03 10:13:13

開(kāi)發(fā)框架

2019-04-02 10:36:17

數(shù)據(jù)庫(kù)MySQL優(yōu)化方法

2022-09-26 09:01:23

JavaScript淺拷貝深拷貝

2013-09-03 11:18:00

Android開(kāi)發(fā)項(xiàng)目

2009-07-16 17:25:44

ubuntu8jdk詳細(xì)安裝Java開(kāi)發(fā)環(huán)境

2020-09-15 06:34:11

Python開(kāi)發(fā)語(yǔ)言

2009-12-16 14:20:16

Visual Stud

2021-07-27 10:52:27

iOS WKWebView容器

2019-08-06 09:11:49

數(shù)據(jù)庫(kù)數(shù)據(jù)結(jié)構(gòu)操作系統(tǒng)

2024-02-26 00:00:00

Redis持久化AOF

2022-07-29 11:39:31

?WindowLinux雙系統(tǒng)

2011-04-01 17:07:24

Zabbix
點(diǎn)贊
收藏

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