Захват window.postMessage в Swift WKWebView - PullRequest
0 голосов
/ 20 июня 2019

Я разрабатываю быстрое приложение для ios, которое использует WKWebView для загрузки сайта электронной коммерции.
Когда пользователь покупает продукт здесь, страница оформления заказа позволяет ему совершать платежи в криптовалюте.

Когда пользователь нажимает кнопку «Открыть в кошельке», сайт снимает window.postMessage(paymentData) где данные платежа - это объект js с URL-адресом биткойна.

Я использую WKUserScript с WKWebConfiguration, чтобы внедрить скрипт, который прослушивает оконное сообщение, а затем запускает данные для моего webkit.messageHandler.

let source = """
    window.addEventListener('message', function(e) { window.webkit.messageHandlers.iosListener.postMessage(JSON.stringify(e.data)) } )
    """

К сожалению, этот код никогда не срабатывает.

Когда я использую Chrome или Safari Devtools для внедрения одного и того же JavaScript, он работает просто отлично.

Я исследовал переполнение стека, чтобы посмотреть, есть ли специальное условие для window.postMessage в WKWebView, но до сих пор не повезло.

Можно ли перехватить событие window.postMessage() и передать данные о событии обратно в мое приложение ios?

Спасибо заранее !!!! Вот мой существующий код.

  let webConfiguration = WKWebViewConfiguration()
    let source = """
    window.addEventListener('message', function(e) { window.webkit.messageHandlers.iosListener.postMessage(JSON.stringify(e.data)) } )
    """
    let script = WKUserScript(source: source, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
    userContentController.addUserScript(script)

    userContentController.add(self, name: "iosListener")
    webConfiguration.userContentController = userContentController
    webView = WKWebView(frame: .zero, configuration: webConfiguration)
    webView.uiDelegate = self
    webView.navigationDelegate = self
    webView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(webView)
 func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    print("message body: \(message.body)")
    print("message frameInfo: \(message.frameInfo)")
  }

1 Ответ

1 голос
/ 20 июня 2019

Да, это возможно.Вам также нужно установить javascriptEnabled = true

self.webView.configuration.preferences.javaScriptEnabled = true

Вы также можете настроить слушателя следующим образом:

self.webView.configuration.userContentController.add(self, name: "iosListener")

И убедитесь, что вы применяете обе команды до

self.webView.load(/*some request*/)

Вы можете сделать простой тест после загрузки страницы didFinish с помощью:

self.webView.evaluateJavaScript("window.webkit.messageHandlers.iosListener.postMessage('test');", completionHandler: { (result, err) in
    if (err != nil) {
        // show error feedback to user.
    }
})

Еще один совет - всегда иметь ; в конце команд в коде JavaScript при взаимодействии с webView поскольку некоторые могут полагаться на стандартный javascript.

let source = """
    window.addEventListener('message', function(e) {
        window.webkit.messageHandlers.iosListener.postMessage(JSON.stringify(e.data));
    });
    """

Примечание: Я бы также предложил иметь webView в качестве переменной класса вместо переменной метода,вы, вероятно, создаете его в viewDidLoad(), я бы посоветовал вам переместить переменную в ваш класс.

var webView: WKWebView!

...