I’ve always wanted to ship an iOS app, and I’m happy to report that this is the year that I’ve finally done it (with help from many of my coworkers, I should say!). That app is Purple Train.
The problem
Purple Train is an answer to a simple question: when do the next MBTA Commuter Rail trains (that I care about) depart? I had tried a few other apps that show this information, but not in an efficient way. I wanted something that I could very quickly open, refer to, and get back to my day.
The solution
By assuming that you commute to Boston from your single “home” train stop, the app offers an easy and efficient interface: choose your home stop, and immediately see the trains that go to and from Boston. If there are express trains that don’t stop at your home stop, they are automatically filtered out, keeping the interface free of distracting noise.
The technology
Frontend
Before I started working on the app, I heard some compelling reasons to use React Native, so I installed it and gave it a try. I wasn’t excited about the idea of writing the app in JavaScript, but I was intrigued by the opportunity for cross-platform development, and I was already familiar with the functional reactive paradigm offered by React and Redux. After being surprised by how productive I could be in React Native, I decided to use it for Purple Train.
Cole Townsend worked on the initial designs for the app, and he felt quite comfortable implementing them with React Native’s StyleSheet support.
After the basic functionality worked on iOS, Justin Kenyon and I spent a half day to get the app working on Android. We were thrilled with how easy this process was. In the end, our application had no platform-specific code; all of that work was abstracted away from us via React Native and a few third party libraries.
Thanks to Blake Williams, Justin Kenyon, Derek Prior, and Mike Borsare for working on the frontend code!
Backend
The backend for the app is an Elixir Phoenix application that caches responses from the MBTA’s Realtime API and serves the mobile app with small JSON payloads that are tailored to the user’s home stop.
The Phoenix app uses the Agent module provided by Elixir to store the cached API responses from the MBTA. This gives us a lightning-fast in-memory store that helps the backend respond with data right away.
There is some logic on the backend that filters out any trips that the user doesn’t care about (such as trips that have already left the user’s station or express trains that don’t go to the user’s home stop). This makes the job of the frontend easier and keeps the JSON responses small, which is important for mobile performance.
Thanks to Derek Prior and Josh Clayton for their help with writing (and re-writing) the backend!
Takeaways
Developers and designers that are used to building for the web can be productive right away with React Native. The language is familiar (JavaScript), the workflow is familiar (Cmd+R or live reloading in the simulators), and the concepts are familiar (functional reactive programming, style sheets).
This familiarity, and the productivity gains it provides, makes React Native a compelling option for many multi-platform mobile apps, despite the pitfalls from using JavaScript.
Elm Native
We like the workflow, we like the concepts, and we’re familiar with the language, but we miss some of the safety and ease of refactoring that we get from “native” compiled languages like Swift and Kotlin.
How can we get the productive workflow without running into JavaScript errors
like undefined is not a function
? Wouldn’t it be cool if we could use the
Elm language so we could feel more confident that our code is correct?
Luckily, the simplicity of the Purple Train app makes it a good testbed to try experimental technologies. Stay tuned for a post about our experience porting Purple Train to Elm using elm-native-ui!
Related
- Read Rapid cross-platform mobile development with React Native
- Listen to the Bikeshed Podcast episode about Purple Train