文章來自簡書做者「APP叫我取個帥氣的暱稱 」:css
http://www.jianshu.com/u/37fe1e005f6c
首先聲明下,WKWebView是蘋果自家的,非第三方。可在Apple Developer Documentation 的API Reference中查到。它是在WWDC 2014隨iOS 8和OS X 10.10出來的。如今的項目應該都基本適配到iOS8了,因此趕忙用起來吧,對比UIWebView,好處那是大大的有啊。它具備java
//和Safari相同的JavaScript引擎; //速度相對較快; //佔用內存相對較小; //與JS的交互更簡便 //等等等等。
在API Reference 中WKWebview給出了以下兩個代理:具體實現下面會講到web
還有個與JS交互相關的代理WKScriptMessageHandler
swift
若是你加載的頁面僅僅是展示給用戶看的,沒啥交互,那麼以下就夠了app
// webView lazy var webView : WKWebView = { let web = WKWebView( frame: CGRect(x:0, y:64,width:ScreenW, height:ScreenH)) /// 設置訪問的URL let url = NSURL(string: "http://www.jianshu.com/u/37fe1e005f6c") /// 根據URL建立請求 let requst = NSURLRequest(url: url! as URL) /// 設置代理 // web.uiDelegate = self web.navigationDelegate = self /// WKWebView加載請求 web.load(requst as URLRequest) return web }()
另外,你也能夠添加個進度條進去ide
// 進度條 lazy var progressView:UIProgressView = { let progress = UIProgressView() progress.progressTintColor = THEME_RED_Color progress.trackTintColor = .clear return progress }()
我這邊是懶加載形式,因此別忘了在func viewDidload()
裏將它們添加到視圖中去,post
view.addSubview(self.webView) view.addSubview(self.progressView)
還有一點 ,若是你加了進度條,也別忘了給它設初值哦,ui
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.progressView.frame = CGRect(x:0,y:64,width:self.view.frame.size.width,height:2) self.progressView.isHidden = false UIView.animate(withDuration: 1.0) { self.progressView.progress = 0.0 } }
extension YourViewControllerName:WKNavigationDelegate{ // 頁面開始加載時調用 func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!){ self.navigationItem.title = "加載中..." /// 獲取網頁的progress UIView.animate(withDuration: 0.5) { self.progressView.progress = Float(self.webView.estimatedProgress) } } // 當內容開始返回時調用 func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!){ } // 頁面加載完成以後調用 func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!){ /// 獲取網頁title self.title = self.webView.title UIView.animate(withDuration: 0.5) { self.progressView.progress = 1.0 self.progressView.isHidden = true } } // 頁面加載失敗時調用 func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error){ UIView.animate(withDuration: 0.5) { self.progressView.progress = 0.0 self.progressView.isHidden = true } /// 彈出提示框點擊肯定返回 let alertView = UIAlertController.init(title: "提示", message: "加載失敗", preferredStyle: .alert) let okAction = UIAlertAction.init(title:"肯定", style: .default) { okAction in _=self.navigationController?.popViewController(animated: true) } alertView.addAction(okAction) self.present(alertView, animated: true, completion: nil) } }
至此,就建立好了一種最簡單隻限於瀏覽用的wkwebview。但如今的項目免不了有交互。下面簡單作個簡單介紹。url
首先,得改下建立WKWebView的代碼,添加進本身的一些配置,代碼以下:spa
lazy var webView : WKWebView = { /// 自定義配置 let conf = WKWebViewConfiguration() conf.userContentController = WKUserContentController() conf.preferences.javaScriptEnabled = true conf.selectionGranularity = WKSelectionGranularity.character conf.userContentController.add(self, name: "和web那邊同樣的方法名") let web = WKWebView( frame: CGRect(x:0, y:64,width:ScreenW, height:ScreenH),configuration:conf) /// 設置訪問的URL let url = NSURL(string: "http://www.jianshu.com/u/37fe1e005f6c") /// 根據URL建立請求 let requst = NSURLRequest(url: url! as URL) /// 設置代理 // web.uiDelegate = self web.navigationDelegate = self /// WKWebView加載請求 web.load(requst as URLRequest) return web }()
conf.userContentController.add(self, name: "和web那邊同樣的方法名")
這裏的name 要和web那邊配合,保持一致的方法名。好比,你在swift項目中寫
conf.userContentController.add(self, name: "testMethodName")
那麼web那邊在H5的代碼就得這樣寫:
webkit.messageHandlers. testMethodName.postMessage("這是我要返回給APP的信息");
接着,要實現WKScriptMessageHandler
的方法
extension YourViewControllerName:WKScriptMessageHandler{//用於與JS交互 func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { if(message.name == "和web那邊同樣的方法名") { print("JavaScript is sending a message \(message.body)") } } }
最後,別忘了在移除MessageHandler
哦!不然可能會致使內存泄漏哦。
override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) //當前ViewController銷燬前將其移除,不然會形成內存泄漏 webView.configuration.userContentController.removeScriptMessageHandler(forName: "和web那邊同樣的方法名") }
以上。