一、WKWebView概述
WKWebView是一个在iOS8及以上版本中推出的基于WebKit引擎的Web视图控件,它可以显示网页,并且支持网页交互。它是在UIWebView的基础上进行了大量改进,比如提高了渲染速度、内存占用更小、JavaScript执行速度更快、支持了WebKit的新特性等。WKWebView主要提供了以下功能:
1、加载Web页面,并且支持显示HTML、CSS、JavaScript等网页内容;
2、通过JavaScript交互,实现Web页面与原生代码的双向通信;
3、可以进行缩放、前进、后退、刷新等基本的Web导航操作;
4、可以显示PDF、图片等非HTML格式的内容。
二、WKWebView常用操作
1、加载网页
if let url = URL(string: "https://www.example.com") { let request = URLRequest(url: url) webView.load(request) }
使用URL初始化一个URLRequest对象,然后通过load函数将URLRequest传入WebView中,即可加载网页。
2、JavaScript交互
// 将函数注入到JavaScript环境中 webView.configuration.userContentController.add(self, name: "myFunction") // 在加载完成的代理方法中注入JavaScript代码 func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { let js = "function myFunction() { /*代码实现*/ }" webView.evaluateJavaScript(js, completionHandler: nil) } // 通过JavaScript调用原生代码 func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { if message.name == "myFunction" { //获取传入的参数 if let dict = message.body as? [String:Any] { //处理数据 } } }
使用add函数将原生代码中的函数名注入到JavaScript环境中,然后在加载完成的代理方法中通过evaluateJavaScript函数将JavaScript代码注入到WebView中,在JavaScript中可以通过window.webkit.messageHandlers.myFunction.postMessage()调用原生代码中的函数。
3、前进、后退、刷新
// 前进 webView.goForward() // 后退 webView.goBack() // 刷新 webView.reload()
使用goForward、goBack、reload函数即可进行基本的导航操作。
三、WKWebView高级操作
1、JavaScript与原生数据交互
// 在JS中调用window.webkit.messageHandlers.getData.postMessage("parameter"); let config = WKWebViewConfiguration() let userContentController = WKUserContentController() let script = WKUserScript(source: "window.webkit.messageHandlers.getData.postMessage('parameter');", injectionTime: .atDocumentEnd, forMainFrameOnly: true) userContentController.add(self, name: "getData") userContentController.addUserScript(script) config.userContentController = userContentController let webView = WKWebView(frame: .zero, configuration: config) // 在原生代码中处理数据 func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { if message.name == "getData" { //获取传入的参数 if let dict = message.body as? [String:Any] { //处理数据 let parameter = dict["parameter"] as? String // 返回数据 let javascript = "yourFunction('\(result)')" webView.evaluateJavaScript(javascript, completionHandler: nil) } } }
在JS中调用window.webkit.messageHandlers.方法名.postMessage('参数')来触发原生代码中的方法,原生代码中通过WKScriptMessage的body属性来获取传入的参数,处理数据后通过evaluateJavaScript函数返回数据。
2、WebView截图
webView.takeSnapshot(with: nil) { (image, error) in if let snapshotImage = image { //处理截图 } }
使用takeSnapshot函数进行WebView截图操作,通过回调函数获取截取到的图片,可以进行后续的处理。
3、网页离线缓存
let url = URL(string: "https://www.example.com") let config = WKWebViewConfiguration() let cachePath = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0] let fullPath = cachePath + "/myCache" let cache = URLCache(memoryCapacity: 4 * 1024 * 1024, diskCapacity: 20 * 1024 * 1024, diskPath: fullPath) config.urlCache = cache if let webView = WKWebView(frame: self.view.bounds, configuration: config) { let request = URLRequest(url: url!, cachePolicy: .returnCacheDataElseLoad, timeoutInterval: 15.0) webView.load(request) view.addSubview(webView) }
使用URLCache可以实现网页离线缓存,提高用户的浏览体验。可以通过设置URLCache的memoryCapacity(内存缓存大小)、diskCapacity(磁盘缓存大小)等属性来控制缓存的大小。在加载网页时,使用URLRequest的cachePolicy属性来设置缓存策略。
四、WKWebView问题处理
1、WebKit内存泄露
在长时间运行的情况下,WKWebView可能会产生内存泄露的问题,一些资源无法释放,导致内存占用越来越高。这时可以通过手动释放资源,以及设置缓存大小等方式来减少内存泄露的风险。
2、JavaScript交互问题
在进行JavaScript交互时,容易出现数据传输错误、JS环境没加载完就调用函数等问题。可以通过设置WKUserContentController的scriptMessageHandler属性来避免出现这些问题。
3、WKWebView加载失败
在加载过程中,可能会出现因为网络等原因导致WebView无法加载页面的问题。可以通过设置config对象的preferences属性的minimumFontSize等属性、request对象的timeoutInterval等属性来提高网页加载成功率。
五、总结
通过以上的阐述,我们可以看到WKWebView是一个功能强大的Web控件。它具备良好的交互性能、高效的渲染速度、完善的JavaScript支持等特点,可以满足多种场景的需求。在使用过程中,需注意处理内存泄露、合理设置缓存、处理好JS交互等问题,以达到更好的用户体验。