WKWebView evaluateJavaScript不返回html

我试图用evaluateJavaScript解析从WKWebView load()返回的html,但它从不打印任何东西。 我这样做了吗? 还有其他方法吗? didFinish确实打印。

import UIKit import WebKit class MyWebViewController: UIViewController, WKNavigationDelegate { var webView: WKWebView! override func viewDidLoad() { super.viewDidLoad() webView = WKWebView(frame: self.view.frame) webView.navigationDelegate = self let url = NSURL (string: "https://google.com"); let request = NSURLRequest(url: url! as URL) webView.load(request as URLRequest) self.view.addSubview(webView) self.view.sendSubview(toBack: webView) } func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { webView.evaluateJavaScript("document.documentElement.outerHTML.toString()", completionHandler: { (html: AnyObject?, error: NSError?) in print(html!) } as? (Any?, Error?) -> Void) print("didFinish") } 

}

evaluateJavaScriptWKWebView使用有点棘手。

由于我认为这个答案对很多人有用,而不是用一个简短的代码片段和一个你需要实现WKScriptMessageHandler的注释来解决你的具体问题,我将发布一个完整的,完整的例子,你可以用来看看一切如何一起工作。

要使用它,在Xcode中创建一个“单视图应用程序”iOS项目,并将其粘贴到默认的ViewController.swift文件中。

 // // WebViewController.swift // WKWebViewExample // // Created by par on 4/2/17. // Copyright © 2017 par. All rights reserved. MIT License. // import UIKit import WebKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let webViewController = WebViewController() // install the WebViewController as a child view controller addChildViewController(webViewController) let webViewControllerView = webViewController.view! view.addSubview(webViewControllerView) webViewControllerView.translatesAutoresizingMaskIntoConstraints = false webViewControllerView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true webViewControllerView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true webViewControllerView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true webViewControllerView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true webViewController.didMove(toParentViewController: self) } } class WebViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler { private var webView: WKWebView! private var webViewContentIsLoaded = false init() { super.init(nibName: nil, bundle: nil) self.webView = { let contentController = WKUserContentController() contentController.add(self, name: "WebViewControllerMessageHandler") let configuration = WKWebViewConfiguration() configuration.userContentController = contentController let webView = WKWebView(frame: .zero, configuration: configuration) webView.scrollView.bounces = false webView.navigationDelegate = self return webView }() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() view.addSubview(webView) webView.translatesAutoresizingMaskIntoConstraints = false webView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true webView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true webView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true webView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) if !webViewContentIsLoaded { let url = URL(string: "https://google.com")! let request = URLRequest(url: url) webView.load(request) webViewContentIsLoaded = true } } private func evaluateJavascript(_ javascript: String, sourceURL: String? = nil, completion: ((_ error: String?) -> Void)? = nil) { var javascript = javascript // Adding a sourceURL comment makes the javascript source visible when debugging the simulator via Safari in Mac OS if let sourceURL = sourceURL { javascript = "//# sourceURL=\(sourceURL).js\n" + javascript } webView.evaluateJavaScript(javascript) { _, error in completion?(error?.localizedDescription) } } // MARK: - WKNavigationDelegate func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { // This must be valid javascript! Critically don't forget to terminate statements with either a newline or semicolon! let javascript = "var outerHTML = document.documentElement.outerHTML.toString()\n" + "var message = {\"type\": \"outerHTML\", \"outerHTML\": outerHTML }\n" + "window.webkit.messageHandlers.WebViewControllerMessageHandler.postMessage(message)\n" evaluateJavascript(javascript, sourceURL: "getOuterHMTL") } // MARK: - WKScriptMessageHandler func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { guard let body = message.body as? [String: Any] else { print("could not convert message body to dictionary: \(message.body)") return } guard let type = body["type"] as? String else { print("could not convert body[\"type\"] to string: \(body)") return } switch type { case "outerHTML": guard let outerHTML = body["outerHTML"] as? String else { print("could not convert body[\"outerHTML\"] to string: \(body)") return } print("outerHTML is \(outerHTML)") default: print("unknown message type \(type)") return } } }