Hybrid mobile apps: Introduction

Bus tracker native

This is part 1 of a series of posts about the conversion of OneSchool's fully native app to a hybrid HTML/native app.

I've been working at OneSchool for seven months now. In that time, I've overseen development of our core product: a mobile application for college students to connect to the people, places, and things around them. We decided to go native on iPhone and Android from the very beginning to provide the best possible user experince. However, lately I've begun to realize that our fully native architecture is increasingly unsustainable.

Our basic architecture involves fully native applications that retrieve data from a central server through a JSON API. The app is then responsible for formatting the JSON into native views to present the data to the user. On the right is our bus route list page. It lists the bus routes available at a campus, and takes the user to the bus tracker view when a route is selected. Despite this view's simplicity, it's surpisingly complex and tedious to implement in native code. Even though we're using the Three20 library and our own abstraction layers to cut down on boilerplate, it requires two Objective-C classes: the controller and data source, with .m and .h files for each.

It gets even worse when one goes beyond the simple views implemented by UIKit and Three20. To implement a custom table cell, which is required to put anything other than unformatted pieces of text in a UITableViewController, even more source files need to be written. First, UITableViewCell needs to be subclassed and populated with the elements to be included in the cell. Then TTTableItem needs to subclassed and tied to the table cell to allow it to be included in the TTTableView. Then a custom data source needs to be written to use the custom table items, and a custom table controller to use the custom data source. After we go through this nightmare for each of our custom views, we end up with an total of 228 Objective-C files in the OneSchool project.

It's clear that a change in technology is needed. HTML5 is a big buzzword these days, and for good reason: HTML5, CSS, and Javascript together can replicate almost anything a native app can do. Plus, if they're hosted server-side, updates can be deployed instantly. But they're not without problems. I tried out several existing technologies to get an idea for where they're at.

I first tried mobile Web frameworks, like jQuery mobile. There's many nice features and UI components in these kinds of frameworks. But after just a few minutes of using them, it's clear that although they're nice for making a more functional mobile version of an existing site, they cannot replace native development. There's a tiny bit of lag on every action that is immediately noticable and annoying when you're used to a native app. And there's no way to access native features such as push notifications or the camera at all.

Bus tracker jQuery mobilePhoneGap looked more promising. It's a native wrapper around a mobile Web site that provides a Javascript/Objective-C bridge that allows for Javascript to access native functions. But it has problems of its own. First, the HTML/CSS/JS is located inside the application bundle itself, eliminating one of the largest benefits of HTML: allowing for instant updates. But even worse, it doesn't solve the lag problem of mobile Web apps. Because it's a simple wrapper, you as the developer are free to use whatever framework you wish. But none of them are good enough to fully replace native development. And because it's a full wrapper, it's difficult to introduce your own native functionality.

Clearly a new approach is needed. There's a few things that native apps are fundamentally good at. For instance, full-page transitions are always much better natively because the native code can take advantage of graphics acceleration and advanced easing algorithms that make the animation instant and fluid. So why not make a hybrid app that combines the best aspects of both HTML and native code?

At the right is a jQuery mobile-rendered list view embedded into our existing native app. Tapping the routes initiates a fully native transition to the existing native tracker view.

In this series of posts, I'll be exploring all the different aspects of making a hybrid HTML/native app, with a focus on iPhone development, though the principles should be the same for other platforms.

Read on to part 2, which covers techniques for seamless navigation between native and HTML parts of your app.