Evaluating Javascript in a Turbo iOS app to call out to Rails app

As referenced in the docs (turbo-ios/Advanced.md at main · hotwired/turbo-ios · GitHub) and in this blog post (Hybrid iOS apps with Turbo – Part 4: The JavaScript bridge | Masilotti.com), I’ve been trying to use session.webView.evaluateJavaScript() to send a JS message to my Rails app.

However, unless I put the evaluateJavaScript() call inside my sessionDidLoadWebView(_ session: Session) method like so:

   func sessionDidLoadWebView(_ session: Session) {
        session.webView.navigationDelegate = self
        let script = "document.body.style.background = 'orange';"
        session.webView.evaluateJavaScript(script) { object, error in
            if let error = error {
                // handle error
            } else if let object = object {
                // success
            }
        }
    }

…the JS doesn’t do anything.

I really need to be able to call evaluateJavascript on demand, doing something like the following in a range of places, e.g after an a native button push, after an in-app purchase is complete, etc.:

let webView = session.webView

let script = "document.body.style.background = 'orange';"  #in reality I'd call a JS method defined within my Rails app here using a JS bridge
webView.evaluateJavaScript(script) { object, error in
    if let error = error {
        // handle error
    } else if let object = object {
        // success
    }
}

Has anybody got something like this working?

I’ve successfully got message handlers set up to receive Javascript messages from the Rails app but have had no luck sending messages the other way around.

Thank you!

Hi,

I have a view controller like defined in the example provided by turbo-ios:

final class APageViewController: VisitableViewController, ErrorPresenter {
    override func viewDidLoad() {
        super.viewDidLoad()

        let javascriptTag = String("Turbo.clearCache()")
        self.visitableView.webView?.evaluateJavaScript(javascriptTag)
    }
}

If it help :slight_smile:

Hi @nodalailama!

Thank you for sharing that code with me!

Is that the only place where you call evaluateJavaScript?

I tried to wrap my script string in String() but that didn’t seem to make a difference.

Ok, Ive seen that, I will try in sessionDidLoadWebView. I ll to y in 2 hours.

@nodalailama Thank you! But it works there! I would like the evaluateJavascript method to work in other methods, on-demand!

For example, in a delegate after an in-app purchase is complete.

So far, I can only get the evaluateJavascript method to work within a message handler as is in shown in the turbo-ios docs, but I want to be able to call the method in other parts of my codebase and send a message directly to my Rails app, without my Rails app needing to trigger a message handler first!

Hum … Sorry, I don’t know.

Okay! Thank you for attempting to help me. I really appreciate it.

Update: Looks like my issue was that I was instantiating a new AppCoordinator instead of passing in the one running my app!

1 Like