As you probably know, Chariot is hosting its annual ETE conference this April. This year we’ve added mobile device support for obtaining all the conference information an attendee would need. This included a mobile browser friendly web site, and both iPhone and Android native applications. I had the pleasure of working on the iPhone application and would like to describe, at a high level, the process and design/implementation decisions that were made along the way.
The Importance of Storyboarding
The first step in designing the mobile application was storyboarding how a user would access the available information about the conference. This turned out to be more valuable than I had imagined. Not only did it define the screens that needed to be developed and the data required by each screen, but the extra value was identifying where screens could be re-used. Given a large part of the application is viewing various lists of sessions, the amount of re-use I was able to attain was impressive and time saving.
Also, when my co-worker Andy Oswald started to work in the Android version of the application, he could follow the same basic flow through the application that I had laid out for the iPhone, albeit designed more to the native Android look and feel.
What about the Data?
The next issue addressed was data access. The initial decision was to access the server side data on an as needed basis. This could be accomplished numerous ways including web services, REST, etc. Since the ETE website was a Rails application, REST seemed like the obvious answer. After a little research, the Objective Resource framework was found. This framework makes the interaction with Rails based web applications easy. It provides a nice abstraction of the REST calls (via either XML or JSON) and object serialization that makes remote data access simple. After some initial experimentation, it was realized that when generating JSON on the server side, Objective Resource did not support the serialization of nested objects on the client side. Since our data model had nested object graphs (Sessions have Speakers, etc.) we were forced to use XML. Sure, we could have modified the framework, but time was not on our side.
Is it really that fast?
So far, so good. We had our screen designs and our remote data access all defined. Development started and progressed nicely. Once the core functionality was developed, I moved the application from the simulator to my iPhone for more realistic testing. Suddenly, the remote data access, and therefore screen loading, seemed a bit sluggish. So, I retrieved the data on a separate thread, added progress screens while data was being retrieved from the server and loaded, and I added some local in-memory caching. This still seemed a bit sluggish, so I investigated using JSON rather than XML. It turns out the JSON was lighter weight and quicker to parse. This required some redesign on both the server side and client side, as we had to flatten out the data model being sent down to the iPhone. This wasn’t too bad and it improved the user experience a good deal. But the application still didn’t seem responsive enough. We kicked around different options for a more persistent local cache, but these tended to introduce what seemed to be too much complexity in staying synchronized with the server. Then Andy Oswald (developer of the ETE Android application) came up with a great solution.
Protocol buffers and local storage for a better experience
He suggested the use of Protocol Buffers to transmit data to the mobile applications. The Rails application would listen for changes to the data and subsequently generate a new protocol buffer file. Our mobile applications would make a request to the server indicating the date of the version of our local file (using the if-modified-since request header), and if a newer version existed in the server, it would return the file. If our version was current, we would receive an HTTP 304 response code. Our applications could then handle the response accordingly. This way, our local data was always synchronized with that on the server.
Since the iPhone application was now going to have a local copy of the server-side data, it was time to re-examine the data access for the application screens. Our data model was small and the relationships were pretty basic, so I decided to pursue the use of Core Data as the new data access and persistence architecture. Core Data provided the ability to deal with objects, abstracted away the actual persistence, and build queries as needed to support the various view the application presented to the users. Also it was quite performant, so the responsiveness and user experience improved greatly. Since the initial design included a nice separation between the view and data access code, this change was pretty non-invasive to implement.
So, in the end I learned the importance of laying out the user interface upfront, testing on the device early and often, and the value of local data (if possible) on the users mobile application experience. We also got a pretty cool application for the ETE 2010 Conference.