Over the last couple of months, we’ve been shipping quite some hybrid iOS and Android apps.
Initially, we were building these apps with RubyMotion, which is excellent for building native apps. But recently, we’ve decided to give Turbolinks 5 and the accompanied iOS and Android adapters a spin.
In this post, I’ll briefly go over some of the things I ran into when wrapping our Rails app into a native iOS app with the turbolinks-ios adapter.
Preparing your Rails app
For the adapter to work, you need to have Turbolinks 5 set up in your Rails app. Rails 5 will include Turbolinks 5 by default. So, for now, you can either choose to upgrade to the latest Rails 5 beta or install the Turbolinks gem manually.
When using Turbolinks, form submissions have to be done via XHR. In your view, this is as easy as adding the remote: true attribute to your form_for tag. However, the response to a form submission does need some more manual changes.
As an example, I’ll take this typical pattern in Rails for saving a model:
For this, I’ve added a SJR response that will replace the current form on the page with the updated form:
Now, when the @post cannot get saved, the view will get updated with the validation errors. Assuming you’re rendering those in the form partial of course.
One of the main advantages of building a Hybrid app is having access to the native APIs. So you'll be able to use things like native interface components, setting up push notifications or leveraging the device's hardware.
By default, the turbolinks-ios adapter uses an implementation of the UIViewController to navigate through web pages. Basically by initiating a new ViewController on each request and adding it to the stack of the NavigationController, which results in a native-like user experience when traversing between screens:
This default iOS navigation bar didn’t match the design of our app, so we decided to hide this navigation bar and let our Rails app render a custom back button. However, we do want this button to behave similarly to the native back button: deallocate the ViewController and slide-animate back to the previous view.
Our desired situation: click link to open new viewcontroller, click back-icon to slide back:
Adding the messageHandler to your wrapper
I’ve added the following code to my ApplicationController.swift:
This code will register the userContentController as Handler for any message the WebView receives with the name closeViewController. The userContentController method will call popViewControllerAnimated(true) which will pop the currently visible view controller.
Calling the method from your Rails app
Note that this button should be either a link- or button tag otherwise the WebView won’t register the taps/clicks.
Questions or comments?
So far, I like the Turbolinks adapters a lot! It provides an excellent starting point for building hybrid apps.
We’re still actively developing with the Turbolinks adapters, so we are going to run into many other challenges from here, but at least we’ll have more stuff to blog about!