WKWebView JavaScript在页面加载时的通信

时间:2019-05-28 13:17:05

标签: javascript swift wkwebview

EDIT

以下示例 DO 有效。我犯了一个愚蠢的错误,没有在我的Web应用程序中调用正确的页面。我将把它留给其他正在寻找如何做我正在做的事情的人。


我有本机-> WKWebView JavaScript通信可用于我的项目,但有一件事情例外:我的网页加载后无法识别postMessage()调用。

我添加了一个名为“ contentLoaded”的消息处理程序,该消息处理程序试图从我的Web视图中触发:

window.addEventListener('load', (event) => {
    window.webkit.messageHandlers.contentLoaded.postMessage("content has loaded");
});

而且我也尝试过:

window.addEventListener('DOMContentLoaded', (event) => {
    window.webkit.messageHandlers.contentLoaded.postMessage("content has loaded");
});

此外,我实际上正在使用Vue.js,因此我也试图像这样钩入Vue的created()mounted()钩子:

mounted() {
    window.webkit.messageHandlers.contentLoaded.postMessage("content has loaded");    
}

或者这个:

mounted() {
    window.webkit.messageHandlers.contentLoaded.postMessage("content has loaded");    
}

这些都不实际触发“ contentLoaded”消息处理程序。

但是,如果我与网页进行了一些交互,我可以触发消息处理程序,例如:

// This works!
button.addEventListener('click', () => {
   window.webkit.messageHandlers.contentLoaded.postMessage("content has loaded");  
})

下面是我代码的Swift面。这里有什么建议吗?

import UIKit
import WebKit

class MainViewController: UIViewController, WKUIDelegate {
    var webView: WKWebView!

    override func loadView() {
        super.loadView()

        let contentController = WKUserContentController()

        contentController.add(self, name: "contentLoaded")

        let webConfiguration = WKWebViewConfiguration()
        webConfiguration.userContentController = contentController
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.uiDelegate = self
        webView.navigationDelegate = self
        view = webView
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let myURL = URL(string:"https://example.com")
        var myRequest = URLRequest(url: myURL!)
        webView.load(myRequest)
    }
}

extension MainViewController: WKScriptMessageHandler {
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        print("received")

        if message.name == "contentLoaded", let messageBody = message.body as? String {
            print(messageBody)
        }
    }
}

extension MainViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        print("didFinish navigation")
    }

    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        print("didStartProvisionalNavigation")
    }
}

1 个答案:

答案 0 :(得分:1)

您是否尝试过使用webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)方法作为窗口加载时的回调,来代替JavaScript回调?

Swift通常在完全加载之前不与WKWebView中的窗口通信-此时,首先调用didFinish方法。假设您只需要知道何时加载窗口/内容,我将在JS上使用该委托方法。

编辑:如果您需要在加载网页时从浏览器中检索某种数据,则可以从didFinish块中调用一个返回Javascript方法的方法,假设您已经编写了这样的Javascript方法。

public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    webView.evaluateJavaScript("getData()", completionHandler: { (data, error) in
        if let data = data {
            print("Received: ", data)
        }
        if let error = error {
            print(error)
        }
    })
}