WKWeb?View

iPhone 應(yīng)該如何運(yùn)行軟件呢?像 OS X 上的應(yīng)用程序,或者 web 頁面,以及 Safari 都應(yīng)該如何運(yùn)行起來呢?仿照 OS X 去構(gòu)建 iPhone OS 的方法已經(jīng)廣泛地被大家熟知了,這種方法到今天也留下了不少爭議。

Web 一直是 iOS 系統(tǒng)上的二級(jí)公民(諷刺的是,其實(shí)現(xiàn)今移動(dòng)網(wǎng)頁響應(yīng)式設(shè)計(jì)的出現(xiàn)大多是 iPhone 推動(dòng)的)。UIWebView笨重難用,還有內(nèi)存泄漏,和 Nirtro JavaScript 引擎談笑風(fēng)生的 Safari 不知道要比它高到哪里去了。

然而,這所有的一切都會(huì)因?yàn)閃KWebView和WebKit框架其他部分的出現(xiàn)而發(fā)生改變。

WKWebView是現(xiàn)代 WebKit API 在 iOS 8 和 OS X Yosemite 應(yīng)用中的核心部分。它代替了 UIKit 中的UIWebView和 AppKit 中的WebView,提供了統(tǒng)一的跨雙平臺(tái) API。

自詡擁有 60fps 滾動(dòng)刷新率、內(nèi)置手勢(shì)、高效的 app 和 web 信息交換通道、和 Safari 相同的 JavaScript 引擎,WKWebView毫無疑問地成為了 WWDC 2014 上的最亮點(diǎn)。

UIWebView&UIWebViewDelegate這個(gè)兩個(gè)東西是如何在 WKWebKit 中被重構(gòu)成 14 個(gè)類 3 個(gè)協(xié)議的呢。雖然這次的變化確實(shí)帶來了不少的新功能,但請(qǐng)一定不要因此感到恐慌!

WKWebKit Framework

Classes

WKBackForwardList: 之前訪問過的 web 頁面的列表,可以通過后退和前進(jìn)動(dòng)作來訪問到。

WKBackForwardListItem: webview 中后退列表里的某一個(gè)網(wǎng)頁。

WKFrameInfo: 包含一個(gè)網(wǎng)頁的布局信息。

WKNavigation: 包含一個(gè)網(wǎng)頁的加載進(jìn)度信息。

WKNavigationAction: 包含可能讓網(wǎng)頁導(dǎo)航變化的信息,用于判斷是否做出導(dǎo)航變化。

WKNavigationResponse: 包含可能讓網(wǎng)頁導(dǎo)航變化的返回內(nèi)容信息,用于判斷是否做出導(dǎo)航變化。

WKPreferences: 概括一個(gè) webview 的偏好設(shè)置。

WKProcessPool: 表示一個(gè) web 內(nèi)容加載池。

WKUserContentController: 提供使用 JavaScript post 信息和注射 script 的方法。

WKScriptMessage: 包含網(wǎng)頁發(fā)出的信息。

WKUserScript: 表示可以被網(wǎng)頁接受的用戶腳本。 > -WKWebViewConfiguration: 初始化 webview 的設(shè)置。

WKWindowFeatures: 指定加載新網(wǎng)頁時(shí)的窗口屬性。

Protocols

WKNavigationDelegate: 提供了追蹤主窗口網(wǎng)頁加載過程和判斷主窗口和子窗口是否進(jìn)行頁面加載新頁面的相關(guān)方法。

WKScriptMessageHandler: 提供從網(wǎng)頁中收消息的回調(diào)方法。

WKUIDelegate: 提供用原生控件顯示網(wǎng)頁的方法回調(diào)。

UIWebView和WKWebView的 API 區(qū)別

WKWebView繼承了UIWebView大部分的接口,這讓 app 來繼承 WKWebKit 也簡單了許多(同時(shí)隨著更新 iOS 8 的越來越多這也成為了某種必需)。

看一下這兩個(gè)類的 API 區(qū)別:


頁面加載


訪問歷史


頁碼

WKWebView目前缺少關(guān)于頁碼相關(guān)的 API。

var paginationMode: UIWebPaginationMode

var paginationBreakingMode: UIWebPaginationBreakingMode

var pageLength: CGFloat

var gapBetweenPages: CGFloat

var pageCount: Int { get }

重構(gòu)分離開的WKWebViewConfiguration

下面這些UIWebView的屬性被重構(gòu)進(jìn)了在初始化WKWebView傳入的設(shè)置對(duì)象:

var allowsInlineMediaPlayback: Bool

var mediaPlaybackRequiresUserAction: Bool

var mediaPlaybackAllowsAirPlay: Bool

var suppressesIncrementalRendering: Bool

JavaScript ?? Swift 對(duì)話機(jī)制

相對(duì)于UIWebView最大的提升就是數(shù)據(jù)在可以 app 和 web 內(nèi)容之間傳遞。

使用用戶腳本來注入 JavaScript

WKUserScript允許在正文加載之前或之后注入到頁面中。這個(gè)強(qiáng)大的功能允許在頁面中以安全且唯一的方式操作網(wǎng)頁內(nèi)容。

一個(gè)簡單的例子如下,用戶改變背景的用戶腳本被插入到網(wǎng)頁中:

Swift

letsource="document.body.style.background =\"#777\";"

letuserScript=WKUserScript(source:source,injectionTime:.AtDocumentEnd,forMainFrameOnly:true)

letuserContentController=WKUserContentController()

userContentController.addUserScript(userScript)

letconfiguration=WKWebViewConfiguration()

configuration.userContentController=userContentController

self.webView=WKWebView(frame:self.view.bounds,configuration:configuration)

WKUserScript對(duì)象可以以 JavaScript 源碼形式初始化,初始化時(shí)還可以傳入是在加載之前還是結(jié)束時(shí)注入,以及腳本影響的是這個(gè)布局還是僅主要布局。于是用戶腳本被加入到WKUserContentController中,并且以WKWebViewConfiguration屬性傳入到WKWebView的初始化過程中。

這個(gè)樣例可以簡單擴(kuò)展為更為高級(jí)的頁面修改方法,例如去除廣告、隱藏評(píng)論等,

web 和 app 通訊機(jī)制也通過 message handler 有很大提升。

就想在Safari 審查元素功能中的console.log能在調(diào)試終端打印信息一樣,網(wǎng)頁中的信息也可以通過調(diào)用這個(gè)函數(shù)被傳到 app 里:

JavaScript

window.webkit.messageHandlers.{NAME}.postMessage()

這個(gè) API 真正神奇的地方在于 JavaScript 對(duì)象可以自動(dòng)轉(zhuǎn)換為 Objective-C 或 Swift 對(duì)象。

Handler 的名字可以通過WKScriptMessageHandler協(xié)議中的addScriptMessageHandler()接口函數(shù)設(shè)置:

Swift

classNotificationScriptMessageHandler:NSObject,WKScriptMessageHandler{funcuserContentController(userContentController:WKUserContentController,didReceiveScriptMessagemessage:WKScriptMessage!){println(message.body)}}letuserContentController=WKUserContentController()lethandler=NotificationScriptMessageHandler()userContentController.addScriptMessageHandler(handler,name:"notification")

于是當(dāng)通知進(jìn)入 app 的時(shí)候,比如說在頁面中創(chuàng)建一個(gè)新對(duì)象,相關(guān)信息就可以這樣傳遞:

JavaScript

window.webkit.messageHandlers.notification.postMessage({body:"..."});

添加用戶腳本來對(duì) web 事件監(jiān)聽并用 Message Handler 將信息傳回 app。

同樣的方法也可以用來收集頁面信息用于 app 的頁面展示或數(shù)據(jù)分析。

例如,如果某人要針對(duì) NSHipster.com 做一個(gè)特別的瀏覽器,就可以加一個(gè)能夠呼出相似文章列表的按鈕:

JavaScriptSwift

// document.location.href == "http://nshipster.com/webkit"functiongetRelatedArticles(){varrelated=[];varelements=document.getElementById("related").getElementsByTagName("a");for(i=0;i

如果你的 app 只是對(duì)網(wǎng)頁內(nèi)容做了很簡單的一層包裝,那么WKWebView可以徹底改變這種狀況。你對(duì)于性能和兼容性的所有愿望都將變?yōu)楝F(xiàn)實(shí)。所有你想要的東西都在這了。

如果你是一個(gè)原生純粹主義者,你可能會(huì)被 iOS 8 新帶來強(qiáng)大和擴(kuò)展性功能嚇到。有一個(gè)秘密就是,例如 Messages 這種原生應(yīng)用都應(yīng)用了 WebKit 來渲染復(fù)雜的頁面元素。你可能尚且沒有意識(shí)到,但事實(shí)是,webview 在移動(dòng)開發(fā)最佳實(shí)踐中應(yīng)該得到一席之地。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容