之前的webview等组件官方已经不支持了,文档中都已经标记废弃了,现在要使用WKWebView,官方说这个新的组件性能更高更安全,建议大家都转这个来使用。具体步骤如下:
1.首先WKWebView所在controller一定要继承WKNavigationDelegate ,WKScriptMessageHandler,xcode会提示你实现扩展方法,一个是webView一个是userContentController,当然还有其他方法可以查阅文档
接下来直接给出代码然后再进行说明
class UserCenterViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler {
lazy var webView: WKWebView = {
let preferences = WKPreferences()
//preferences.javaScriptEnabled = true
let configuration = WKWebViewConfiguration()
configuration.preferences = preferences
configuration.userContentController = WKUserContentController()
//注册changePwdByJS这个函数,让js调用
configuration.userContentController.add(self, name: "changePwdByJS")
configuration.userContentController.add(self, name: "getUserInfoByJS")
var webView = WKWebView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height), configuration: configuration)
webView.scrollView.bounces = true
webView.scrollView.alwaysBounceVertical = true
webView.navigationDelegate = self
return webView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
automaticallyAdjustsScrollViewInsets = false
view.addSubview(webView)
//加载H5页面
let myURL = URL(string: H5_SERVER + USER_CENTER)
let myRequest = URLRequest(url: myURL!)
webView.load(myRequest)
}
@objc private func goBackMenu() {
webView.evaluateJavaScript("goBackMenuByIOS()") { (result, err) in
// print("goBackMenuByIOS")
// print(result)
// print(err)
}
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
//web加载好了才有左边按钮
leftBtton = UIButton()
leftBtton.setImage(UIImage(name:"back"), for: .normal)
leftBtton.addTarget(self, action: #selector(goBackMenu), for: .touchUpInside)
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: leftBtton)
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print("-------------" + message.name)
if message.name == "changePwdByJS" {
print(message.body as! [String])
}else if message.name == "getUserInfoByJS" {
//进入个人中心的时候,H5调我获取下用户的数据
let user = UserDefaults.standard
let json = JSON([
USER_NAME: user.string(forKey: USER_NAME) as Any,
USER_ID: user.string(forKey: USER_ID) as Any,
])
let s: String = json.rawString()!
webView.evaluateJavaScript("getUserInfoByIOS(" + s + ")", completionHandler: nil)
}
}
}
2.swift调用js,切记一定要等加载完了才能调用,这个带有didFinsh参数的webView被自动调用的时候就是加载完页面的时候,假如说有个按钮是要点击下弹出个网页,这个时候可以在webView这个方法中初始化这个按钮并为它加事件,因为这样可以保证这个按钮被点击的时候网页被加载完了,这样就不会报错说js未加载完
@objc private func goBackMenu() {
webView.evaluateJavaScript("goBackMenuByIOS()") { (result, err) in
// print("goBackMenuByIOS")
// print(result)
// print(err)
}
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
//web加载好了才有左边按钮
leftBtton = UIButton()
leftBtton.setImage(UIImage(name:"back"), for: .normal)
leftBtton.addTarget(self, action: #selector(goBackMenu), for: .touchUpInside)
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: leftBtton)
}
2.js调用swift,上面代码样例中注册了两个函数changePwdByJS,getUserInfoByJS,这两个函数可以被JS调用,具体就是下面这段代码,没啥好解释的应该都能明白
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print("-------------" + message.name)
if message.name == "changePwdByJS" {
print(message.body as! [String])
}else if message.name == "getUserInfoByJS" {
let user = UserDefaults.standard
let json = JSON([
USER_NAME: user.string(forKey: USER_NAME) as Any,
USER_ID: user.string(forKey: USER_ID) as Any,
])
let s: String = json.rawString()!
webView.evaluateJavaScript("getUserInfoByIOS(" + s + ")", completionHandler: nil)
}
}