Lets review. Just five years ago, of about 219M mobile subscribers in the U.S., just 9.1M of them hadever used a “downloaded application”. Today, there are far more than 9.1M new smartphones being sold-through to consumers every week, and mobile apps go hand-in-hand with unwrapping a new smartphone. Combine that with the fact that there are 4.5M companies running QuickBooks, and you’ve got all of the ingredients for putting the power of QuickBooks into the hands of on-the-go businesspeople everywhere. Want to be sure that the folks carrying smartphones are the same folks that want to get to QuickBooks data on-the-go? Try looking at time-series relative search volume for the terms “QuickBooks Mobile” or “Intuit App”, and you might find yourself running, not walking, to your mobile app engineers.
Before You Do File→New Project
Before you crank out the first line of code, you might put some thought into your revenue model, because it may impact your architecture. For this post, I’m going to assume that you have a SaaS revenue model, because that’s the clear trend amongst Intuit App Center apps in general. At issue is the question of whether you should plan on building a mobile app that connects directly to Intuit Data Services, or whether you should build a mobile app that connects to your own web server that enables or supports the data flowing to and from Intuit Data Services.
If you decide on a SaaS revenue model, you’ll probably want the primary flow of data to pass through your own web server, rather than directly from the mobile app to Intuit Data Services. That way it’ll be a lot easier for you to manage access rights based on business rules around your subscription packages. I’m not saying this is the only way to architect a SaaS app, but it does seem to be the most mainstream approach. For the purposes of this blog post, I’ll assume that you are building a mobile app that has a SaaS revenue model, and that you’ll use a custom server-side in part as a passthrough for inbound and outbound data being exchanged with Intuit Data Services.
First Things First
You are going to need some way for users to sign in. You could homebrew your own account creation, sign in, and authentication code. Whatever the reason, that seems to be a popular choice. However, I’ll bet that you don’t consider your sign-in process to be the core of your differentiation, and if that’s the case I’d suggest letting someone else bear that burden. Specifically, by relying on an Intuit Account sign-in with OpenId integration, you can rid yourself of the responsibility of building a sign-in and authentication system from scratch.
Want to know which sign-in pages Intuit has optimized for viewing on a mobile device? Try launching your web browser with a User-Agent that urges Intuit’s web server to send you a mobile-formatted version of the page. For example, on a Mac with Google Chrome, you could open your browser window via a shortcut like:
open /Applications/Google\ Chrome.app --args -user-agent="Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3"
Launching your browser with that type of User-Agent, for example, causes the App Center sign-in page to show you it’s mobile version:
If you’ve built any mobile apps in the past, you probably already know how to get an embedded web browser into your app (Android: WebView; BlackBerry: BrowserContent; iOS: UIWebView). You can easily point an embedded web control to Intuit’s URL, to let the mobile device’s native browser handle the rendering and user interaction of Intuit’s mobile-formatted sign-in page.
Once you’ve got a skeleton app that presents this mobile sign in page in a probably full-screen web control, you’ll need to put some thought into a strategy for doing an OpenId assertion driven by your custom web-side code, to complete the cycle of establishing a session between your mobile device and your custom server. And, you won’t have to write a lick of password storage or retrieval code. Thanks, OpenId!
Tackling the Try-Buy flow from a mobile device is an advanced topic for another time — but the above should get you going if you’ve already got a desktop-side Try-Buy flow that is the primary starting point for first-time users.
Hybrid App Basics
I’ve already urged you to hand Intuit the responsibility for maintaining the sign-in UI, and to use OpenId to cause your device<=>server session to be authenticated by Intuit. If you do all of that, then you are probably at a point where you are thinking about hiding the embedded web control upon successful sign-in, and thinking about how to transition to your native UI that exposes the main functionality of the app.
You’ve heard that hybrid apps are all the rage, and that HTML5 is making hybrid apps even more attractive, and anytime you find yourself mixing embedded web controls with native UI you are essentially building a hybrid app. So, how does a hybrid app maintain the continuity of device<=>server session when it’s initiated via an embedded web control, but later used by your app’s network connection code (like Android: HttpURLConnection; BlackBerry: HttpURLConnection; iOS: NSURLConnection)? Although there may be some oddball exceptions, the vast majority of device<=>server session management for embedded web browsers is handled via session cookies. The rules by which the session cookies are issued and invalidated end up being specific to web server, configuration, and server-side code base, but a search for the following terms will lead you to abundant information about the most popular session handling semantics: JSESSIONID, PHPSESSID, ASP.NET_SessionId, sid.
Once you nail down the nature of your web server’s Set-Cookie headers (try Firebug or Chrome Developer Tools to verify your understanding), you are well on your way to writing mobile app code to manage the hand-off of the relavent session cookies from your embedded web browser to your customized device-side network connection code.
Consuming and Sending Data
At this point, you have a user that is authenticated by Intuit, with a session established between the mobile device and your server, and we’ve made the assumption that the Try-Buy flow was handled via a desktop-side first-use experience. If you’ve made it this far, you are in a position to begin exchanging data with IDS via your server, with the sends/receives either happening synchronously when your mobile app requests it, or asynchronously to do some predictive caching of resources that you anticipate your mobile app will need frequently. If you’ve written much web service code for use from mobile devices, you’ve probably settled on a RESTful design, and my suggestion would be that the mobile<=>server interactions should pass XML bodies that conform to the IDS data models. After all, if the destination or source of the data is IDS, and if you are aiming for a seamless integration with QuickBooks, it seems undesirable to invent an intermediate XML schema for mobile<=>server interactions. If you are worried about the “heaviness” of some of the IDS-returned XML bodies, you could certainly cull the nodes that you know your mobile app won’t consume.
I’d recommend having class definitions, parsers, and serializers for the IDS objects that you rely on most heavily. Without getting into the always-heated debate of what design pattern is most appropriate, let me suggest that in basic terms you’ll want to be able to pass around IDS objects in an object type that makes sense on your mobile device.
For example, on iOS, having objects that conform to NSObject puts you within striking distance of being able to conform to additional protocols (like NSCoding) that will take some of the load off your developers when they get around to implementing local caching of IDS objects.
We’re Out of Time, But…
There is so much more to say, for example, about:
- Managing asynchronous connections to make the QuickBooks data-driven scenarios “feel” just as snappy as if they were local to the device
- Developing a caching strategy, and a method of keeping track of dirtied objects and resolving conflicts
- Using the server-side to shield your mobile device code from having to know whether the data source is QBO or QBD
…however, these and other topics will have to wait for a future post.
Phillip Leslie is Founder & CEO of ProOnGo LLC, maker of ProOnGo Expense and numerous other QuickBooks-compatible mobile apps. He can be reached at phillip at proongo.com