蘋果在iOS8中推出了webkit新框架,提供了WKWebview組件用來替換存在各種問題的UIWebview,用WKWebview加載網頁,相較于UIWebview速度更快了,內存占用更少了。WKWebview還提供了更加豐富的接口,功能更加強大,真是喜大普奔的好事兒,下面就讓我們看看如何使用WKWebView吧!
WKWebView的優勢:
1)WKWebview在性能、穩定性上和UIwebview相比
2)WKWebView更多的支持HTML5的特性
3)WKWebView更快,占用內存可能只有UIWebView的1/3 ~ 1/4
4)WKWebView高達60fps的滾動刷新率和豐富的內置手勢(Built-in gestures)
5)WKWebView具有Safari相同的JavaScript引擎Nitro(JJT四個進程解釋執行優化js代碼)(Fast JavaScript)
6)WKWebView增加了加載進度屬性
7)app和網頁的交互更簡便(Easy app-webpage communication)
8)響應滾動(Responsive scrolling)
9)更省電量 (battery)
1.加載網頁
func setUpWKwebView() {
let webConfiguration = WKWebViewConfiguration()
let myURL = URL(string: "https://weibo.com")
webView = WKWebView(frame: view.bounds, configuration: webConfiguration)
let myRequest = URLRequest(url: myURL!)
webView.load(myRequest)
view.addSubview(webView)
}
2.WKWebView的代理方法
WKWebView提供了WKNavigationDelegate
和WKUIDelegate
兩個代理協議
-
WKNavigationDelegate
提供了可用來追蹤加載過程的代理方法
//頁面開始加載時調用
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!);
//當內容開始返回時調用
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!);
// 頁面加載完成之后調用
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!);
//頁面加載失敗時調用
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error);
也提供了可用來監聽頁面跳轉的代理方法,分為:收到跳轉與決定是否跳轉兩種
// 接收到服務器跳轉請求之后調用
func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!);
// 在收到響應后,決定是否跳轉
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) ;
// 在發送請求之前,決定是否跳轉
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) ;
-
WKUIDelegate
WKWebView創建初始化加載的一些配置
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView?
與界面彈出提示框相關的代理方法,針對于web界面的三種提示框(警告框、確認框、輸入框)分別對應三種代理方法。
//處理網頁js中的提示框,若不使用該方法,則提示框無效
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void)
//處理網頁js中的確認框,若不使用該方法,則確認框無效
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void)
//處理網頁js中的文本輸入
func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void)
iOS9.0中新加入的,處理WKWebView關閉的時間
func webViewDidClose(_ webView: WKWebView)
在 iOS 10 中新加入的用于自定義Peek and Pop的代理方法
func webView(_ webView: WKWebView, shouldPreviewElement elementInfo: WKPreviewElementInfo) -> Bool;
func webView(_ webView: WKWebView, previewingViewControllerForElement elementInfo: WKPreviewElementInfo, defaultActions previewActions: [WKPreviewActionItem]) -> UIViewController?
func webView(_ webView: WKWebView, commitPreviewingViewController previewingViewController: UIViewController)
當用戶觸摸元素時webView(_:shouldPreviewElement:)
立即被調用。返回false將完全禁用該元素的預覽,并且阻止其他方法的調用。返回true將提供一個自定義視圖控制的機會,前提是用戶觸摸時有足夠的力度來啟動查看。
如果用戶輸入Peek,那么webView(_:previewingViewControllerForElement:defaultActions:)
為其提供了一個定制視圖控制器的機會。返回任何非空視圖控制器都會導致視圖控制器顯示為Peek
預覽。defaultActions
參數是一個活動數組,WebKit
默認使用它作為previewActionItems
。如果想要使用這些活動中的任何一個,你只需從視圖控制器的previewActionItems
執行結果中返回即可。
如果用戶用足夠的力觸摸來彈出視圖控制器,webView(_:commitPreviewingViewController:)
將被調用。
3.Swift與JS交互
動態加載并運行JS代碼
// js代碼片段
let jsStr = "var checkBtn = document.getElementsByClassName('check_box');for(var j = 0;j < checkBtn.length; j++){checkBtn[j].onclick = function(){this.removeAttribute('checked');}}"
// 根據JS字符串初始化WKUserScript對象
let userScript = WKUserScript(source: jsStr, injectionTime:.atDocumentEnd, forMainFrameOnly: true)
let userContentController = WKUserContentController()
userContentController.addUserScript(userScript)
// 根據生成的WKUserScript對象,初始化WKWebViewConfiguration
let webConfiguration = WKWebViewConfiguration()
webConfiguration.userContentController = userContentController
let userWebview = WKWebView(frame: CGRect.zero, configuration: webConfiguration)
view.addSubview(userWebview)
webView 執行JS代碼
用戶調用JS代碼,一般指服務端開發的:
webView .evaluateJavaScript(<#T##javaScriptString: String##String#>, completionHandler: <#T##((Any?, Error?) -> Void)?##((Any?, Error?) -> Void)?##(Any?, Error?) -> Void#>)
JS 調用 Native APP
-
WKScriptMessageHandler
這個協議中包含一個必須實現的方法,這個方法是提高App與web端交互的關鍵,它可直接將接收到的JS腳本轉為Swift對象。
// 從web界面中接收到一個腳本時調用
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)
1.首先添加WKScriptMessageHandler代理
extension ViewController:WKScriptMessageHandler
2.實現userContentController的代理方法
func userContentController(userContentController: WKUserContentController!, didReceiveScriptMessage message: WKScriptMessage!) {
if(message.name == "callbackHandler") {
println("JavaScript is sending a message \(message.body)")
}
}
3.WebView啟動對JavaScript的監聽事件
contentController.addScriptMessageHandler(
self,
name: "callbackHandler"
)
4.在H5中,添加如下js
webkit.messageHandlers.callbackHandler.postMessage("Hello, webkit!");