一、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交互等问题,以达到更好的用户体验。