This is the third blog post in the "Batman" series and will shed some light on our approach for a mobile UI for the application. It's been quite some time since we worked on the app but we'll try to account for some of the key struggles and victories that we encountered.
The team working on BatMobile was us (Henrik Lehtonen & Mikko Junnila) along with Stefano Garusi. We all had some previous experience from working with mobile applications with Xamarin and also from the Windows Phone world, but for BatMobile we wanted to use React Native, which seemed to be gaining traction and popularity in the field. Helping our start, Mikko was already a battle-scarred veteran on this field which made adventuring with the tech and learning the ropes while getting the project underway rather swift.
Platform-wise we decided to go for both iOS and Android so that we could get a feel for multi-platform development with the stack. This ended up throwing a few monkey wrenches into the works since at that point React Native was still only in development for the Android side and while on the iOS side virtually all of the native components were available, that wasn't the case for Android.
Our goals for the application were quite simple (read more about the actual device and backend from the previous posts in case these don't make sense :)
- Show a listing of the bat-men
- Show the charge status of each device
- Provide a map location view for the devices
As a technical example for the differences in iOS, the picture below shows the basis of their approach. The idea is that the view controller layer doesn't consist of traditional React Native components. Instead, the components being used are native.
It's worth mentioning that this approach is not perfect because predictable state "leaks" to the native side, and using libraries like Redux with it can be tricky. Another popular navigation option is ex-navigation by the awesome team at Exponent. There is also a new standard navigation library just released by the React Native team.
For state management, we picked MobX because of it's "lighter" nature (supports transition from OOP thinking towards functionality) compared to redux and other approaches. MobX basically makes the application state observable and has the possibility to use values that are automatically derived from state when changes occur.
Since our domain was very simple but we still wanted to have good control over our application state, we estimated that this would be a good match for us.
Below is a code snippet displaying our state and how some computed values for the battery state and charge are calculated. By offering the values as observable, MobX handles the recalculations of computed values when changes occur.
Because of his previous experience with the stack, Mikko was able to get his flow going quite quickly and ended up doing the bulk of the solution (virtually the whole iOS side) while the others spent time learning the syntax, functional / immutable approaches to problems instead of the ones they were used to etc. Still, even if this sounds harsh and you're hesitant of picking up this kind of stack because of the steepish learning curve, don't be; once you climb the first hill, the whole flow starts to make sense and there's a lot of valuable stuff to take into other projects as well (e.g. event based thinking and the benefits of functionality).
The use cases for the BatMobile app were quite simple. That's why the UI itself doesn't have much to it. Basically we wanted to list the batteries being monitored and show more specific data for each battery.
Because we collect the voltage from the battery continuously, we thought it would make sense to show how the voltage has changed over time. For this we used victory-native library by FormidableLabs.
- Don't be afraid to dive into the deep end: we've been working on a new React Native project lately and all of the experience from this adventure have been of great use.
- Prepare to spend around the same amount of time/effort to working on a mobile project as you would for a web one. There are similar architectural decisions in both web projects and mobile projects. Also, even if the screen is smaller, the usability takes all of the excess time you've got.
React Native pros
- Build/run/test cycle is awesome especially with hot reloading enabled. We were able to iterate a UI very quickly compared to say recompiling and running new versions of a native app with XCode or Android Studio.
- React's "learn once, write anywhere" model helps web developers move to mobile development. Concepts can be new but easy to reason about and teach.
React Native cons
- React Native is changing all the time and fast. When we were working on BatMobile, React Native was at version 0.25.1. Today it's already at 0.42. I (Mikko) used to do upgrades from React Native's early versions, which didn't always go so smoothly. Hopefully this will get more smoother as the React Native matures.
- When you're making changes with hot reloading enabled everything is great. Sometimes getting there is difficult with Android. You might need some retries, even restarts. For example the Android Debug Bridge (adb) had some issues recently that slowed us down a bit.
A good tip is to work with iOS emulator to a certain point and then switch to an actual Android device to make the final UI changes.
Code & links
The source code for BatMobile is available at our GitHub: