首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WKWebView evaluateJavaScript不返回html

WKWebView evaluateJavaScript不返回html
EN

Stack Overflow用户
提问于 2017-04-03 00:34:29
回答 2查看 18.6K关注 0票数 7

我试图用evaluateJavaScript解析从WKWebView load()返回的html,但是它从来没有打印出任何东西。我这样做对吗?还有别的办法吗?didFinish可以打印。

代码语言:javascript
复制
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")

}

}

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-04-03 03:00:40

WKWebView中使用evaluateJavaScript有点棘手。

由于我认为这个答案对许多人都很有用,而不是通过实现WKScriptMessageHandler所需的简短代码片段和注释来解决您的特定问题,因此我将发布一个完整的示例,您可以使用它来了解所有内容是如何协同工作的。

要使用它,请在Xcode中创建一个"Single View Application“iOS项目,并将其粘贴到默认的ViewController.swift文件上。

代码语言:javascript
复制
//
//  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://stackoverflow.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
        }
    }
}
票数 23
EN

Stack Overflow用户

发布于 2021-10-01 15:06:13

我知道这已经有一段时间了,我发现这对我来说并不是真的有效。我使用了下面的代码。

在添加setTimeout()函数之前,我无法让evaluateJavaScript工作。下面是我的代码,很有价值。

代码语言:javascript
复制
webView.evaluateJavaScript("setTimeout(function(){ 
// Do something here
},10);") { (result1, error) in
            if error == nil {
                print(result1 ?? "")
            }
        }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43170736

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档