7

I am trying to inject a custom WebKit script message handler. My controller is correctly loaded and the view as well. However, on the JS side (from the Safari console), window.webkit.messageHandlers is empty. Any idea why? My app is using iOS 8.1 but even by upgrading to 9.2, it did not work.

import Foundation
import UIKit
import WebKit

public class FooController: UIViewController, WKScriptMessageHandler {
    private var wkWebView: WKWebView?

    public override func viewDidLoad() {
        super.viewDidLoad()

        let o = WKUserContentController()
        o.addScriptMessageHandler(self, name: "foo")
        let config = WKWebViewConfiguration()
        config.userContentController = o

        self.wkWebView = WKWebView(frame: self.view.bounds, configuration: config)
        self.view.addSubview(self.wkWebView!)

        self.wkWebView!.loadRequest(NSURLRequest(URL: NSBundle.mainBundle().URLForResource("foo", withExtension: "html")!))
    }

    public func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
        print("foo")
    }
}
Adrien Cadet
  • 1,191
  • 1
  • 13
  • 21

2 Answers2

9

webkit.messageHandlers is not an Array. It is a UserMessageHandlersNamespace.

Try

var message = {"key1":"value1", "key2":"value2", "dictionary": {"name": "foo"}}
webkit.messageHandlers.foo.postMessage(message);

In your message handler.

public func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
    let body = message.body
    if let dict = body as? Dictionary<String, AnyObject> {
        print(dict)
    }
}
Onato
  • 8,758
  • 4
  • 42
  • 52
  • Hey Onato, thanks for your answer. I know `messageHandlers` is an object. But it has no key at all, and especially `foo` is missing. – Adrien Cadet Jan 13 '16 at 15:28
  • 1
    Your swift code worked fine for me. Can you post how you are calling your message handler or checking for the existence of "foo"? – Onato Jan 13 '16 at 20:38
  • Arf. Just retested and it works fine. Sorry for the confusion. However, I have a different issue now. I cannot post any custom data. I tried to post a dictionary with 2 strings and another dictionary and the body I received only included a single string. Not a big deal, but do you know anything about that? – Adrien Cadet Jan 13 '16 at 21:56
  • Awesome! It works fine. I was trying to cast the body as a `NSDictionary` but it did not work as expected. – Adrien Cadet Jan 14 '16 at 00:05
-2

In the below javascript code, message is mandatory.

var message = {"key1":"value1", "key2":"value2", "dictionary": {"name": "foo"}}
webkit.messageHandlers.foo.postMessage(message);

The following javascript code without the message parameter,

webkit.messageHandlers.foo.postMessage();

did not invoke the func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) as expected

cnu
  • 423
  • 3
  • 8