1

I want to call a swift function from java script code which returns the device id back to the script, I had added the code that use currently. Please advise how to return the value back to the java script from the swift function, Thanks in advance

Code Snippet :

     super.viewDidLoad()
    {
    self.webView = WKWebView()
    let preferences = WKPreferences()
    preferences.javaScriptEnabled = true
    let configuration = WKWebViewConfiguration()
    configuration.preferences = preferences
    configuration.userContentController = contentController
    configuration.userContentController.addScriptMessageHandler(self,name: "interOp")
    self.webView = WKWebView(frame: self.view.frame, configuration: configuration)
    print(self.view.frame)
    self.view = self.webView
    webView!.navigationDelegate = self
    let url = NSURL(string:"http://softence.com/devTest/vb_ios.html")
    let req = NSURLRequest(URL:url!)
    self.webView!.loadRequest(req)

    }

// did receivescript message is working fine
func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage)
{
    let sentData = message.body as! NSDictionary
    print(sentData)
    if sentData["name"] as! String == "DeviceInfo"
    {
        self.DeviceInfo()
    }
}
// i want to return the following device info to javascript
func DeviceInfo() -> String
{
let dict = NSMutableDictionary()
    dict.setValue(UIDevice.currentDevice().model, forKey: "model")
    dict.setValue(UIDevice.currentDevice().name, forKey: "name")
    dict.setValue(UIDevice.currentDevice().systemVersion, forKey: "system_version")
    return String(dict)
}
2
  • 1
    FYI JavaScript is one word... ;) Commented Sep 22, 2016 at 7:37
  • 1
    You can use this answer, in case you got to do it in synchronous way. Commented Mar 25, 2018 at 9:26

1 Answer 1

2

Try having a look at the evaluateJavaScript(_:, completionHandler:) function on WKWebView as described here

To use that, your DeviceInfo function should define the complete JavaScript string which you would like to execute.

So for instance if you had a JavaScript function defined like so:

showDeviceInfo(model, name, system_version) {

}

Then your DeviceInfo function could look something like this:

func deviceInfo() {
    let model = UIDevice.currentDevice().model
    let name = UIDevice.currentDevice().name
    let systemVersion = UIDevice.currentDevice().systemVersion

    let javaScriptString = "showDeviceInfo(\(model), \(name), \(systemVersion));" //string your JavaScript string together from the previous info...and no...it aint pretty :)
    webView.evaluateJavaScript(javaScriptString, completionHandler: nil)
}

You could also return javaScriptString from your DeviceInfo function and then call it in your userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage), the important things are:

  1. you need to define the entire JavaScript string you would like to execute
  2. you need to call evaluateJavaScript

Hope that helps you.

Sign up to request clarification or add additional context in comments.

7 Comments

hi thanks for your reply... i tried sending a simple string through evaluateJavaScript method, but nothing is reflected and shows 'undefined' in the web page. And also i dont want to send the data, java script has to call the swift function automatiically and get the value returned from the swift function @pbodsk
what did the string you sent look like? It has to be valid JavaScript. About "JavaScript has to call the swift function automatically", it is, isn't it? You call the Swift function from your JavaScript which calls didReceiveScriptMessage. That again calls deviceInfo() that will generate a JavaScript string which calls your JavaScript function, filled with the correct data. Or am I misunderstanding what you mean? Hope I'm making sense
yeah you are correct I'm asking whether we can call the swift function directly from the java script code without sending a message to the swift code as like in android.
As I understand it, you can not, you have to use the WKUserContentController as a sort of bridge between your JavaScript code and your native code, as you've set up in your example above. Once you call window.webkit.messageHandlers.interOp.postMessage(someDataHere); that is detected by your WKUserContentController and didReceiveScriptMessage is called, giving you the possibility to figure out exactly which JavaScript function was called. To send data the other way, you can use the method I've tried to describe above
have a look at this article: priyaontech.com/2014/12/native-–-js-bridging-on-ios8-using-wkwebview/ or this one nshipster.com/wkwebkit hope they can help you understand whats going on :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.