细节
解
根据马特的答案
protocol ScriptMessageHandlerDelegate: class {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)
}
class ScriptMessageHandler: NSObject, WKScriptMessageHandler {
deinit { print("____ DEINITED: \(self)") }
private var configuration: WKWebViewConfiguration!
private weak var delegate: ScriptMessageHandlerDelegate?
private var scriptNamesSet = Set<String>()
init(configuration: WKWebViewConfiguration, delegate: ScriptMessageHandlerDelegate) {
self.configuration = configuration
self.delegate = delegate
super.init()
}
func deinitHandler() {
scriptNamesSet.forEach { configuration.userContentController.removeScriptMessageHandler(forName: $0) }
configuration = nil
}
func registerScriptHandling(scriptNames: [String]) {
for scriptName in scriptNames {
if scriptNamesSet.contains(scriptName) { continue }
configuration.userContentController.add(self, name: scriptName)
scriptNamesSet.insert(scriptName)
}
}
func userContentController(_ userContentController: WKUserContentController,
didReceive message: WKScriptMessage) {
delegate?.userContentController(userContentController, didReceive: message)
}
}
完整样本
不要忘记在此处粘贴解决方案代码
import UIKit
import WebKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 40))
button.setTitle("WebView", for: .normal)
view.addSubview(button)
button.center = view.center
button.addTarget(self, action: #selector(touchedUpInsed(button:)), for: .touchUpInside)
button.setTitleColor(.blue, for: .normal)
}
@objc func touchedUpInsed(button: UIButton) {
let viewController = WebViewController()
present(viewController, animated: true, completion: nil)
}
}
class WebViewController: UIViewController {
private weak var webView: WKWebView!
private var scriptMessageHandler: ScriptMessageHandler!
private let url = URL(string: "http://google.com")!
deinit {
scriptMessageHandler.deinitHandler()
print("____ DEINITED: \(self)")
}
override func viewDidLoad() {
super.viewDidLoad()
let configuration = WKWebViewConfiguration()
scriptMessageHandler = ScriptMessageHandler(configuration: configuration, delegate: self)
let scriptName = "GetUrlAtDocumentStart"
scriptMessageHandler.registerScriptHandling(scriptNames: [scriptName])
let jsScript = "webkit.messageHandlers.\(scriptName).postMessage(document.URL)"
let script = WKUserScript(source: jsScript, injectionTime: .atDocumentStart, forMainFrameOnly: true)
configuration.userContentController.addUserScript(script)
let webView = WKWebView(frame: .zero, configuration: configuration)
self.view.addSubview(webView)
self.webView = webView
webView.translatesAutoresizingMaskIntoConstraints = false
webView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
webView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
view.bottomAnchor.constraint(equalTo: webView.bottomAnchor).isActive = true
view.rightAnchor.constraint(equalTo: webView.rightAnchor).isActive = true
webView.load(URLRequest(url: url))
}
}
extension WebViewController: ScriptMessageHandlerDelegate {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print("received \"\(message.body)\" from \"\(message.name)\" script")
}
}
信息清单
添加您的Info.plist传输安全设置
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>