Why HTML5 Didn’t Cut It For Us (the Ladders job app)
While we initially thought that PhoneGap’s smaller learning curve would be an asset for us as non-iOS developers, we quickly discovered that PhoneGap has its own peculiarities and technical challenges. The resulting experience looked and felt substantially less polished than that of a native app. Before long, we’d abandoned it.
As it turns out, the QA process of testing the app on iOS and all the various flavors and screen sizes of Android proved to be quite a chore. We spent countless days and weeks trying to massage the PhoneGap code into something that presented itself adequately on all platforms. We had to make painful trade-offs, which hurt the experience. Ultimately it was only released for iOS and proved to not be a successful product. We pulled it from the App Store.
PhoneGap was not the only reason the app wasn’t a hit, but it might have been symptomatic of a misguided approach. The goal of “write once, run everywhere” is a noble one. On the back end, most of the code being written today and deployed in production around the world is running on virtual machines. Java, Python, and Ruby all compile to bytecode and run seamlessly in a virtual machine on a variety of platforms. Native code is getting rarer. No one is writing a website in C. Native languages are increasingly niche platforms for circumstances where raw performance is paramount. You won’t see Call of Duty written in Java or Final Cut Pro in Ruby anytime soon, but you can bet a vast majority of the Internet’s websites are running on a virtual machine neatly distanced from whatever hardware is underlying.
The success of this virtualized approach on the back end has not materialized on the front end. Early cross-platform GUI toolkits like Java Swing helped change “write once, run everywhere” to “write once, debug everywhere.” Aside from the challenge of debugging on all possible platforms, user interface norms and patterns vary wildly from platform to platform. Mac OS X does not look or feel anything like Windows 8. Compounding the problem, cross-platform UI toolkits don’t mirror any of them.
Embracing Native App Development
So when the time came to work on our job-seeker app a year later, we bit the bullet and went native. We thought the smoother, more consistent and polished experience we could achieve with a native solution would pay off with our customers. With a strong engineering team, mastering Cocoa on iOS proved to be far easier than we thought. Lots of documentation and a strong developer ecosystem actually resulted in us moving much faster with native code than PhoneGap, and the app looked and felt much more modern.
The major disadvantage to this approach was that Android had to be developed completely separately. However, a lot of the complexity is generally in the service layer and we made sure to have an extremely clean and well documented REST API supporting the app. We chose to figure out the experience on iOS first and then port Android using the same REST service layer.
We began working on Android in September of 2013 and had a final build around Thanksgiving. With an iOS app serving as a prototype in hand and plenty of documentation and examples of the REST API, it was a pretty quick build. We also had the freedom to change parts of the UI to match the accepted Android UI idioms and gestures.
Of course, there are subtle and stark differences between iPhones and Android devices that your app must account for. Android has a very different navigation mechanism than iOS. Android devices also have a physical back button, so there’s no need to put one on the screen. The additional buttons on Android phones also make having bottom menu or toolbars cumbersome, and accidental clicks are common.
Going native really allowed us to effectively manage these issues and tailor the look, feel, navigation, and gestures of the app to the specific platform. Aside from solutions like PhoneGap, options like Titanium exist, which compile JavaScript into native code and use native widgets. With these options, even though you have native widgets, you’ll still need to somehow resolve the platform differences like back button versus no back button.
It’s all been a learning process, but we’ve moved through the conception to delivery phases relatively quickly and have now released a total of three apps for job seekers and recruiters. For now we are sticking with separate native implementations: We develop on iOS then write a native Android port. So far it’s working for us, but we like to reserve the right to change our minds.