WKWebView JavaScript связь при загрузке страницы - PullRequest
0 голосов
/ 28 мая 2019

EDIT

Приведенные ниже примеры DO работают. Я сделал глупую ошибку и не набрал нужную страницу в своем веб-приложении. Я оставлю это здесь для всех, кто ищет то, что я делаю.


У меня Native -> WKWebView. Связь JavaScript работает для моего проекта, за исключением одного: я не могу распознать вызов postMessage() при загрузке моей веб-страницы.

Я добавил обработчик сообщений с именем «contentLoaded», который я пытаюсь вызвать следующим образом из моего веб-просмотра:

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, поэтому я также пытался подключиться к created() и mounted() крюкам Vue, например:

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");  
})

Свифт сторона моего кода ниже. Любой совет здесь?

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 Ответ

1 голос
/ 28 мая 2019

Вы пытались использовать метод webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) в качестве обратного вызова при загрузке окна вместо обратного вызова javascript?

Swift обычно не взаимодействует с окном в WKWebView, пока не будет полностью загружен - в этот момент первым вызывается метод didFinish. Предполагая, что вам просто нужно знать, когда загружается окно / контент, я бы использовал этот метод делегата через JS.

Редактировать: Если вам нужно получить какие-то данные из браузера при загрузке веб-страницы, вы можете вызвать метод Javascript из блока didFinish, который возвращает его, предполагая, что вы написали такой метод 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)
        }
    })
}
...