Killermatch Tech Talk: Native, Responsive, Cordova or React Native?

May 18th, 2015, by Marius Kjeldahl

Some four years ago I decided it was time to deep dive into the mobile platforms (better late than never). I had actually started doing a bit of mobile development a few years earlier (pre iPhones) on the first Symbian and Windows mobiles, but it wasn't much fun to be honest. Shortly after the iPhone launched, and changed everything.

I've spent most of my life in startups (either my own or somebody else's), but raising a family typically ate into the time that can be spent living the startup life. About the same time I decided to deep-dive into developing for mobiles, I was lucky enough to land a paid job giving me plenty of time to dig into both the high- and low-level details of modern mobile phones.

While learning Android I wanted an actual project to work on. At the time the running/jogging tracker apps were all the rage (Runkeeper, Runtastic, Endomondo etc). As an eager squash player I decided I would implement a match diary for racket sports. That became Killermatch 1, a true Android native app with a Node.js+PostgresSQL powered backend (screenshots below):

The app is pretty simple. It allows you to input individual matches you play. The app will then calculate various statistics related to how often you play, and win (both in total and against each player). The app also allowed you to combine match results with photos and share on social media, similar to how weather apps are often used. The app was released in the Google Play Store during Spring 2013.

While the app is pretty simple, it has a few interesting features. For instance the app and it's back-end server supports offline operation and syncing databases between multiple devices. If you're interested in how it works, I've pretty much implemented the protocol I have described on Stack Overflow.

I got a few friends to use it, but there was one big flaw; around half of my squash buddies use an iPhone. The app only ran on Android.

Keep in mind this was just a project to scratch my own itch (I wanted it!) and to have as a test case to learn how the Android platform and ecosystem actually work. In total it got a few hundred downloads, of which maybe hundred became regular users.

Since I also needed to investigate iOS, I started working on an iOS native version of the app as well. However at this time, the initial two-year project I had doing security research on mobile phones was coming to an end, and I was thinking about what I wanted to do next. Somewhat co-incidentally I became involved in a new great startup (Kahoot!). Initially as an investor and tech advisor, but shortly after as a full-time employee. Kahoot was/is a busy place, and as much as we wanted to polish our mobile apps, there simply wasn't enough time for me to spend any time on Killermatch (other than to keep it operational).

In March 2015, I quit Kahoot as a full time employee and moved back into my role as tech advisor (see my blog post about Leaving Kahoot!). I finally had some time on my hands again. Based on the feedback I had gotten on Killermatch and from talking to friends in the racket sport business, I decided to take the time to spend a bit more time on Killermatch again, at least making sure it ran on iPhones as well as Android.

I'll be quite frank; as much as I love a lot of things in iOS (the user experience, the devices, the consistency of most things, a nice flat UI), Objective-C (the primary programming language on iOS) isn't one of the things I love. I also do no love tools that more or less force me into using IDEs, combining coding with GUI drag-and-drop editors (XCode, Storyboard etc). I prefer my code editor separately (Emacs), with separate tools for builds. Creating interactive/visual tools for helping newbies doing layout is fine, but please make sure it outputs something human readable (and writable..), so the actual usage of the tool is optional. Let's just say XCode isn't quite there yet.. :‑)

Since I last worked on Killermatch, Apple released a new programming language, named Swift. It's a lot more modern than Objective-C, and it seems to have very good inter-op with Objective-C, meaning it can support and/or replace it as needed. Similar to Objective-C (today), Swift is only used on the Apple platform. For some parts of Killermatch that had to interface with iOS native code I have already used Swift for writing a Cordova plugin. Compared to writing Objective-C, writing code in Swift is a joy.

When I decided to finally make sure Killermatch supports iOS, I had some choices to make. First of all I wanted to support more or less all platforms. "All" here means the web browser, Android and iOS. For the web browser there is only one language; javascript. For Android you need to use Java (or any other language targeting the JVM, but you still need to understand Java). For Apple you can use Objective-C or Swift, but similar to the Java situation on Android, you pretty much need to understand Objective-C (and the NextStep object hierarchy) as well.

On the server side, there are also choices. Node.js (or it's fork, IoJS) is pretty decent, has good performance up to a point, and allow you to code in javascript (same as in the web browser). If you really want to think ahead on maximum bang for the buck, you probably should look into JVM, Go or even Erlang based platforms.

In my case, I pretty much will write everything myself. There is a limit to how many languages and architectures I can juggle around in my head simultaneously, so for the backend I will continue to use Node.js and javascript. Regardless of the other choices, that gives me a common language for the server backend and the web front-end (yeah, there are still differences in architecture, but I know most of this stuff already).

So which language/tool should I select for the iOS implementation?

Before answering that question, there are a couple of other technologies that have been around for a few years which have become pretty mature. There is Cordova (previously known as Phonegap), which pretty much allows you to write whole- or parts of your application using web technology (javascript) on mobile platforms. And more importantly, these apps can be packaged and served through the Apple App Store and Google Play Store.

Another more recent option for iOS development is React Native (from Facebook). React Native allow you to write your application in javascript using the popular framework already in use in many web applications (ReactJS). App/component layout is done using JSON, following the Flexbox model known from modern CSS. Facebook have also promised support for Android, but so far only iOS support is available.

Weighting all the options against all the constraints (me being the only developer, and with limited time available), I decided to re-implement Killermatch using javascript, using Cordova for the Android and iOS version. From this point of view, Killermatch went from being a native application to what is commonly known as a hybrid application (javascript, using non-native web-based GUI elements).

The downside of having one (non-native) code base is that the app probably feels a bit off, at least for iOS users. The UI is more or less Android's Action Bar pattern, but reimplemented to run inside Cordova (it does not use the native ActionBar component that Android offers). For tech users this will be very obvious, and even feels annoying sometimes. However for most of the users I have spoken with so far, they do not notice one way or the other. They care a lot more about the actual features in the app. That does not mean I would not like to give them a native experience on all platforms, but one thing at a time.

Regardless, these choices were also made based on the hope that pretty soon React Native will be a better option for Android and iOS than Cordova if you want to maximize code-base re-use and/or want/need one language for most of your app. When React Native finally launches for Android I should be able to do another implementation of Killermatch, re-using a lot of the existing code, but now also supporting the native GUI navigation and elements of iOS and Android. I'm already using ReactJS in my responsive web and cordova client, and I consider it a very good framework. Moving to React Native should be fairly easy.

Having finally made these choices, I was able to re-implement Killermatch from scratch in around five weeks, supporting responsive web, Android and iOS (through Cordova). I also took some time to redesign how the application looks, as can be seen below:

I submitted the app to Google and Apple and the app was approved on the first attempt. Google took a few hours, Apple took 8 days.

In my next Killermatch tech-talk blog post I will talk about specific challenges I met while implementing Killermatch, including storage issues, online/offline issues, interfacing native code (cordova plugins), IAP (In-App-Purchases) and various browser issues.

The followup tech-talk is already live here.