文章来自简书做者“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那边同样的方法名") }
以上。