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.
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"