笔者性懒,腹中无墨.
以下简单列出WKWebView的使用及注意事项.
1. 初始化webview, 一般设置如下, 支持javaScript交互.
fileprivate lazy var webView: WKWebView = {
let webConfiguration = WKWebViewConfiguration()
webConfiguration.preferences = WKPreferences()
webConfiguration.preferences.minimumFontSize = 0
webConfiguration.preferences.javaScriptEnabled = true
webConfiguration.processPool = WKProcessPool()
webConfiguration.preferences.javaScriptCanOpenWindowsAutomatically = true
let webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.backgroundColor = .white
webView.isOpaque = false
webView.uiDelegate = self
webView.navigationDelegate = self
webView.allowsBackForwardNavigationGestures = true
return webView
}()
2. 添加视图
添加视图在viewDidLoad()里, webview的uiDelegate和navigationDelegate最好也在这里指定, 防止App还未加载完该页面, 因某种原因或需求调用deinit()方法时, 找不到代理而出错.
//防止App还未加载完该页面, 因某种原因或需求调用deinit()方法时出错.
webView.uiDelegate = self
webView.navigationDelegate = self
view.addSubview(webView)
webView.snp.makeConstraints {
(make) in
make.edges.equalTo(UIEdgeInsets.zero)
}
webView.addSubview(topBlueView)
3. 新建WKScriptMessageHandler协议类
支持js交互的话, webview需要实现WKScriptMessageHandler协议, 它提供了从网页中运行的JavaScript接收消息的方法.
这里我们把这个协议的实现独立出来, 新建一个WKScriptMessageDelegate类, 交由代理实现上述协议, 注意代理的弱引用.
import UIKit
import WebKit
class WKScriptMessageDelegate: NSObject {
//这里建议使用弱引用, 以免造成循环引用问题
weak var scriptDelegate: WKScriptMessageHandler?
init(delegate: WKScriptMessageHandler?) {
scriptDelegate = delegate
}
deinit {
print("WeakScriptMessageDelegate is deinit")
}
}
extension WKScriptMessageDelegate: WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
scriptDelegate?.userContentController(userContentController, didReceive: message)
}
}
4. 控制器懒加载WKScriptMessageDelegate
lazy var wkDelegate: WKScriptMessageDelegate = {
let d = WKScriptMessageDelegate(delegate: self)
return d
}()
5. 加载URL, 注意缓存问题, 根据项目需求修改
///加载url
private func loadUrl() {
guard let webUrl = webUrl, let url = URL(string: webUrl) else {
return
}
// MARK: - 未设置则使用默认缓存规则, 即: 若请求协议头保持为no-cache, 表现为直接从后台请求数据, 则不需修改.
webView.load(URLRequest(url: url))
/**
case useProtocolCachePolicy
case reloadIgnoringLocalCacheData
case reloadIgnoringLocalAndRemoteCacheData
case returnCacheDataElseLoad
case returnCacheDataDontLoad
case reloadRevalidatingCacheData
*/
}
6. 对于 js调用native :
由js触发, 先约定好方法名, 原生需要先注册该方法.
第一步: 原生注册及移除方法
可直接添加添加交互事件, 也可根据当前webview的类型添加.
///web类型与事件监听
private func configWeb() {
//调用此webview都会添加unLogin方法.
webView.configuration.userContentController.add(wkDelegate, name: FunctionName.unLogin.rawValue)
switch webType {
//仅当webview类型为contract时, 会添加的方法
case .contract