1

I am trying to wait for javascript callback, however, the swift callback is being called before the javascript callback. How can I wait for JS callback?

AppWebView.evaluateJavaScript("$('.loading-gif').removeClass('hide', function() { return true } );") { (Any, Error) in
\\ .loading-gif successfully hided.
}

3 Answers 3

2

There is no way to do this using evaluateJavaScript, since it's callback is called as soon as the evaluated Javascript returns. This is most likely before your asynchronous call is done.

You will need to register a message handler in your swift code similar to…

let script = WKUserScript(source: javascriptString, 
                          injectionTime: injectionTime, 
                          forMainFrameOnly: true)
userContentController.addUserScript(script)
webView.configuration.userContentController.addScriptMessageHandler(self, 
                                            name: "didShowLoading")

You can then define a delegate method in your Swift code…

func userContentController(userContentController: WKUserContentController,
    didReceiveScriptMessage message: WKScriptMessage) {

    if message.name == "didShowLoading" {
        // do something
    }
}

Finally, you can post the message from your javascript code…

var script = "$('.loading-gif').removeClass('hide', function() {"
           + "  webkit.messageHandlers['didShowLoading'].postMessage('');"
           + "});"
webView.evaluateJavaScript(script)
Sign up to request clarification or add additional context in comments.

1 Comment

What is the difference between javascriptString and script (in the bottom snippet)?
2

You can use this library https://github.com/marcuswestin/WebViewJavascriptBridge

On JS side:

bridge.registerHandler("show_loading", function(data, responseCallback) {
    $('.loading-gif').removeClass('hide', function() { 
     responseCallback(true) 
    } );
})

And on Swift side:

self.bridge.callHandler("show_loading",data:nil, handler: { (data:AnyObject!) in
            //do whatever you want...
        })

Comments

2

You could notify the native iOS code via a callback from the javascript callback. If you add something like this to your javascript:

window.webkit.messageHandlers.observe.postMessage(JSON.stringify( { callback: 'show_loading' } ));

Then on the native side setup a WKUserContentController for your WKWebView (installed on the WKWebViewConfiguration). Your userContentController.didReceiveScriptMessage handler will get called with the JSON sent from the Javascript side.

Comments

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.