最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - userContentController never called back from JS injection - Stack Overflow

programmeradmin1浏览0评论

I've got a WBWebview running into a NSPopover.
I've followed this guide in order to be able to send data back to my Swift application from JS. Unfortunately, userContentController is never called in the Swift app. Here's my Swift app View controller code:

class GSViewController: NSViewController, WKScriptMessageHandler, WKNavigationDelegate {

    var webView: WKWebView?

    var webConfig:WKWebViewConfiguration {
        get {

            // Create WKWebViewConfiguration instance
            let webCfg:WKWebViewConfiguration = WKWebViewConfiguration()

            // Setup WKUserContentController instance for injecting user script
            let userController:WKUserContentController = WKUserContentController()

            // Add a script message handler for receiving  "buttonClicked" event notifications posted from the JS document using window.webkit.messageHandlers.buttonClicked.postMessage script message
            userController.addScriptMessageHandler(self, name: "buttonClicked")

            // Get script that's to be injected into the document
            let js:String = buttonClickEventTriggeredScriptToAddToDocument()

            // Specify when and where and what user script needs to be injected into the web document
            let userScript:WKUserScript =  WKUserScript(source: js, injectionTime: WKUserScriptInjectionTime.AtDocumentEnd, forMainFrameOnly: false)

            // Add the user script to the WKUserContentController instance
            userController.addUserScript(userScript)

            // Configure the WKWebViewConfiguration instance with the WKUserContentController
            webCfg.userContentController = userController;

            return webCfg;
        }
    }

    override func loadView() {
        super.loadView()
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        self.webView = WKWebView(frame: self.view.frame, configuration: webConfig)
        self.webView!.navigationDelegate = self
        self.view = webView!

        let username = NSUserName()
        let url = NSURL(string:"someUrl")
        let req = NSURLRequest(URL:url!)
        self.webView!.loadRequest(req)
        self.view.frame = CGRectMake(0, 0, 440, 600)
     }

    func buttonClickEventTriggeredScriptToAddToDocument() ->String{
        let script:String = "webkit.messageHandlers.callbackHandler.postMessage('Does it works?');"
        return script;

    }

    // WKNavigationDelegate
    func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
        NSLog("%s", #function)
    }

    func webView(webView: WKWebView, didFailNavigation navigation: WKNavigation!, withError error: NSError) {
        NSLog("%s. With Error %@", #function, error)
        showAlertWithMessage("Failed to load file with error \(error.localizedDescription)!")
    }

    func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
        print("called")
        if(message.name == "callbackHandler") {
            print("It does ! \(message.body)")
        }
    }

    // Helper
    func showAlertWithMessage(message:String) {
        let myPopup:NSAlert = NSAlert()
        myPopup.messageText = message
        myPopup.alertStyle = NSAlertStyle.WarningAlertStyle
        myPopup.addButtonWithTitle("OK")
        myPopup.runModal()
    }

}

I'm trying to inject directly the call to Swift callback webkit.messageHandlers.callbackHandler.postMessage('Does it works?');, but it seems not to work.

With different test, I've discovered that the injection actually works in the Swift -> JS way (I've been able to modify CSS of visible HTML elements via injection of JQuery code), but the JS -> Swift bridge just doesn't seem to make it. Does anyone have an idea why?

I'm under OSX 10.11.6, running XCode 7.3.6.

I'm really new into Swift and OSX programming in general, so doesn't hesitate to point out any element I'm missing. I'm voluntary omitting the JS my page uses, since I'm not using any of it in the example.

Thanks.

I've got a WBWebview running into a NSPopover.
I've followed this guide in order to be able to send data back to my Swift application from JS. Unfortunately, userContentController is never called in the Swift app. Here's my Swift app View controller code:

class GSViewController: NSViewController, WKScriptMessageHandler, WKNavigationDelegate {

    var webView: WKWebView?

    var webConfig:WKWebViewConfiguration {
        get {

            // Create WKWebViewConfiguration instance
            let webCfg:WKWebViewConfiguration = WKWebViewConfiguration()

            // Setup WKUserContentController instance for injecting user script
            let userController:WKUserContentController = WKUserContentController()

            // Add a script message handler for receiving  "buttonClicked" event notifications posted from the JS document using window.webkit.messageHandlers.buttonClicked.postMessage script message
            userController.addScriptMessageHandler(self, name: "buttonClicked")

            // Get script that's to be injected into the document
            let js:String = buttonClickEventTriggeredScriptToAddToDocument()

            // Specify when and where and what user script needs to be injected into the web document
            let userScript:WKUserScript =  WKUserScript(source: js, injectionTime: WKUserScriptInjectionTime.AtDocumentEnd, forMainFrameOnly: false)

            // Add the user script to the WKUserContentController instance
            userController.addUserScript(userScript)

            // Configure the WKWebViewConfiguration instance with the WKUserContentController
            webCfg.userContentController = userController;

            return webCfg;
        }
    }

    override func loadView() {
        super.loadView()
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        self.webView = WKWebView(frame: self.view.frame, configuration: webConfig)
        self.webView!.navigationDelegate = self
        self.view = webView!

        let username = NSUserName()
        let url = NSURL(string:"someUrl")
        let req = NSURLRequest(URL:url!)
        self.webView!.loadRequest(req)
        self.view.frame = CGRectMake(0, 0, 440, 600)
     }

    func buttonClickEventTriggeredScriptToAddToDocument() ->String{
        let script:String = "webkit.messageHandlers.callbackHandler.postMessage('Does it works?');"
        return script;

    }

    // WKNavigationDelegate
    func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
        NSLog("%s", #function)
    }

    func webView(webView: WKWebView, didFailNavigation navigation: WKNavigation!, withError error: NSError) {
        NSLog("%s. With Error %@", #function, error)
        showAlertWithMessage("Failed to load file with error \(error.localizedDescription)!")
    }

    func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
        print("called")
        if(message.name == "callbackHandler") {
            print("It does ! \(message.body)")
        }
    }

    // Helper
    func showAlertWithMessage(message:String) {
        let myPopup:NSAlert = NSAlert()
        myPopup.messageText = message
        myPopup.alertStyle = NSAlertStyle.WarningAlertStyle
        myPopup.addButtonWithTitle("OK")
        myPopup.runModal()
    }

}

I'm trying to inject directly the call to Swift callback webkit.messageHandlers.callbackHandler.postMessage('Does it works?');, but it seems not to work.

With different test, I've discovered that the injection actually works in the Swift -> JS way (I've been able to modify CSS of visible HTML elements via injection of JQuery code), but the JS -> Swift bridge just doesn't seem to make it. Does anyone have an idea why?

I'm under OSX 10.11.6, running XCode 7.3.6.

I'm really new into Swift and OSX programming in general, so doesn't hesitate to point out any element I'm missing. I'm voluntary omitting the JS my page uses, since I'm not using any of it in the example.

Thanks.

Share Improve this question asked Dec 6, 2016 at 16:30 Shikatsu KagaminaraShikatsu Kagaminara 3514 silver badges17 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 3

Found it, was totally my bad. I forgot to rename the message handler when I added my script to the webview configuration.

userController.addScriptMessageHandler(self, name: "callbackHandler") // was originally "ButtonClicked"
发布评论

评论列表(0)

  1. 暂无评论