A few weeks ago I read the transcript of a talk by Dave Fetterman about Facebook’s decision to move to a HTML5 hybrid solution for their iOS applications. It interested me because we faced a lot of the same challenges here at Zoosk, and yet came to some very different conclusions.
Since we just released our own iPad application, now seems like a good time to discuss our own approach and how it compares with theirs. Our own platform is certainly not apples to apples with Facebook’s, but I don’t think the most obvious difference—size—has had as much impact on our choice of technologies as you might think. We are both large social platforms; we both have mobile apps with similar features; we both migrated from pure web to WAP to native mobile.
So we could certainly do as Facebook does and drop big pieces of Zoosk into webkit widgets. And why don’t we? Well, Dave himself makes a pretty good case for not doing it towards the end of his talk. According to him, the main problems they ran into were: the application did not look quite native, did not feel native, and was slow. One other cost he conspicuously omits is the cost in terms of having a buggy, crash-prone app for the better part of a year but, again: “hiring manager”. Yikes… well surely there’s a big up side to balance all that out, right? In exchange for their trouble, they now have a unified codebase, the ability to circumvent Apple’s review system for many updates, and a fairly consistent feature set across their products.
Those are definitely some pretty cool things, but is it really a silver bullet of platform unification? I would say it may very well be the right choice for Facebook given their deep web integration. I would also venture to say that if their level of integration is deep enough to make quality development on other platforms unrealistic, that represents a real dependency risk to their future business. Not a huge one, but it is there. Facebook is a web company. They make no bones about the fact that they have hitched their wagon to HTML, and it is not coming unhitched at this point. Fair enough—there are far worse horses to tie up to. But if you are incapable of spooling up a native incarnation of your product on new platforms in a reasonable amount of time, that is worrisome.
Enough about Facebook, what about us?
As Zoosk has grown over time, we have also felt the pain of a growing feature matrix. Unlike Facebook, we chose to tackle this by investing heavily in an API driven architecture through which all of our platforms and features are supported. All of our clients use them. Our desktop application uses them. Even our website uses them. I am not saying Facebook doesn’t have an API. I am just saying that, for whatever reason, they have clearly had trouble making it robust and platform-agnostic. To make this combination of central APIs and distributed clients work for us, we focus on three main things.
1. Model Layer, Model Layer, Model Layer.
One of the biggest problems you face as your feature matrix expands is reconciling the growing amount of data arriving from different sources. We take a lot of our lessons in how to handle it from database theory. At the end of the day, all you are really want to do with an inbound API is replicate the information in your server’s database locally. Obviously you can’t just transmit everything, so what do you do? You de-normalize the relevant information and pass it along. What you do not want to do is anticipate the end use and tailor your API to that. I can not stress that enough. What you should do is consider what pieces of information are required to support a given scenario, and design your API based on that information alone. Strongly de-coupling the data model from any sort of presentation assumptions is a lesson we are always re-learning. This coupling may not be completely obvious either. Even paging of result sets, or embedding URLs makes certain assumptions about client capabilities. At some point making some assumptions is unavoidable—we assume a client can parse XML or JSON for example—but you should really think long and hard about what assumptions you are making, and how they might change in the future.
If the API’s job is to de-normalize data for transmission, it is the client’s job to take that data and normalize it back into a coherent model. This can be handled in very discrete, testable chunks. If one of our APIs returns user nodes, each one gets parsed and the single user object in our local cache gets updated. That update automatically notifies any controls listening for changes and they, in turn, perform their own discrete updates. This is our key to rapid client development—small controls that are capable of abstracting away all the details we don’t care about to get things done. Focus on your model layer, break your controls into modules, and feature additions will become much easier. Entirely new data sources can be plugged into existing parsers and all we have to do is drop UI components where we want them.
2. Remote control.
Once you begin distributing application logic, another problem you will encounter is that you necessarily give up some level of control over feature behavior. In this regard, Facebook’s technique certainly has the advantage. We attempt to narrow the gap with a default tendency towards feature parametrization. What I mean by that is that we have flags to control not just feature availability, but centralized parameters for nearly every aspect of client behavior. Even our www site behavior can be controlled in this way. Everything from page sizes of inbox requests to refresh rates, form validation regexes, etc are all communicated remotely via an API that our clients fetch at launch.
3. Fail safe.
For features that we can’t anticipate, we always try to design our applications to be tolerant of unexpected changes. This may be as simple as ensuring that our parsers don’t complain about extra nodes. Often it is a more deliberate process of consistently writing code that has safe fallback behavior if server responses change, or are missing. In this way, the new features may not be available immediately on all devices, but they tend to be available in a slightly degraded form until we push out a new client. This approach has the added benefit of making our clients relatively tolerant of different types of unexpected failures along the network stack. If our API servers go down, you hopefully get a nice little notice about it, not a screen full of broken dreams.
Double clients… what does it meeeeeean?
For all of Facebook’s trumpeting about rapid iteration, I really think they throw too much baby out with their bath water when it comes to tablets. On the iPhone handset form factor, the tradeoffs they have made are really not a huge deal. They lack a few native interactions and some scrolling performance, but the mobile site feed looks pretty close to what could be accomplished with a native table view.
With their iPad application however, the tradeoffs are just glaring. Just take a look at the screenshot at the beginning of this post. It looks pretty good for a mobile website, but really bland for an iPad app. iPad is the platform where we developers are expected to show off our concept car, not a scaled up mobile feed. Such a waste of a beautiful opportunity to showcase the future of their product. And I believe that at least one former iPhone engineer would agree with that sentiment.
The difference you really can’t appreciate from the screenshots is the feel of interacting with the application. I encourage you to download our iPad app and play around with the Search and News profile feeds. They really feel like something native and different from what a website can deliver. It might be possible to replicate that interaction through webkit windows, but it would be extremely resource intensive and I doubt iPad 1 hardware is up to the task. I couldn’t be happier with how those interactions turned out, and it is an great testament to our designers and developers that they delivered an entire iPad application in under two months. That kind of turnaround is only possible when you have a solid foundation to build on, and I think we’ve done well in that regard.