Chapter 8. Long Term Maintenance of iOS Enterprise Applications

So, you’ve got an app in the store, people are starting to download and use it, and since you read this book from end to end, it went without a hitch and you’re a hero at your company. Alas, your job has just begun. Now you have to support that sucker!

Of course, this is true of any software that has to actually be put in the hands of end users. Wouldn’t life be so much easier without them? But, since you have them, you’re going to need to deal with them in the long term. This presents one particular challenge for enterprise developers, and it’s what this chapter is all about.

If your application connects to some resource in the cloud that’s under your control, you can close this book and crack open a beverage of your choice. But if it connects to a backend server that isn’t under your control, and which may exist at multiple version levels at the same time, read on.

A classic example of the first scenario is Salesforce. Individual customers don’t install the Salesforce server—they use the common one in the cloud, and it is always at a given API level and server version. If Salesforce wants to release a new iPhone app, all they have to do is make sure that it lines up with one of the current versions of the API living on their servers, and they’re golden.

But what about a scenario where your application is going to have to connect to multiple different versions of the server? In the case of the app I developed, our customers can take a year or more to actually place a new server version into production use, so we were facing the very real possibility of having to support 4 or 5 years worth of different APIs as we enhanced the backend functionality to add new features to the app.

No problem, you say: just have the users install the right version of the app for the API version they connect to. Sounds good, but remember that with the App Store, you can only have one version of the application available for download at any one time, and it can be automatically updated if they connect to iTunes. So short of telling customers not to upgrade their app, you have no way to keep them from downloading a new, incompatible version. And worse, that means that you have no way of distributing bug fixes to them. So, to quote the old American Express commercials, what will you do?

Option 1: The Perpetually Compatible Application

One way to approach the problem is to keep your application perpetually back-compatible with every version of the API that has ever existed. It’s not impossible, especially if you’re clever about it. What you want to avoid is sprinkling your API integration code with conditionals everywhere. A more modular approach is to use a protocol to define your API functions, and use different implementing classes to handle different API versions. Then on first connect to the server, you can figure out which API version you’re talking to, and provision the correct implementing class to talk to it.

On the surface, this doesn’t look like a bad option, at least until you start thinking through to the next level of code. Suppose version 1.0 of our BuggyWhipChat application connects to version 1.0 of the backend API, and supports features A and B. Version 2.0 of the app connects to version 1.1 of the backend API, and supports A, B, and C. You don’t know at first glance if the application is going to connect to a 1.0 or 1.1 backend, so you have to conditionalize your UI and business logic—not just your API interface code—to handle either possibility. It can get even worse when features on a single screen have to be conditionalized. You can end up with an app that is essentially thousands of “if” statements flying in close formation.

Now multiply that times 5 or even 10 different backend API versions, and you can imagine how messy your application code can end up. Depending on how aggressive you are about sunsetting support for older server versions, it can quickly become a nightmare, particularly for testing, as you’ll have to regression-test all new application versions against all the supported server versions.

And think about what happens if you do sunset support for an old server version. What happens to the customers who refuse to upgrade? The next time their application updates from the App Store, it will break. I suppose that’s one strategy to get your customers to keep up their support contracts, but it may not be a very politically popular one.

(Non-)Option 2: The Perpetually Compatible Server

A little thought will make it clear that trying to place the compatibility requirement on the server side is a non-starter. Remember, the problem is not with an out-of-date client, since we can pretty much assure that the client will always be the latest version (and enforce it with upgrade messages inside the app that force the user to upgrade before proceeding). The problem is with an out-of-date server, which can’t support all the new or changed features of the app.

There’s no way to build forward-compatibility into a server, and the client will still have to conditionalize on what comes back in the payload from the server. So, we’re back to square one.

Option 3: App Store Version Roulette

What you’d really like to do is to match a specific server version to a specific app version, so that you keep down the conditional code inside your app and reduce your testing matrix nightmare. Your Android brethren have this base covered, because you can directly download Android applications to the phone without going through an app store, at least with most carriers. But along with the added security of the iTunes App Store, you also lose the ability to directly install apps, unless you’re a developer.

What you can do is place multiple products in the app store, each basically a version of the application specific to a given server backend. So, in essence, you’d have Buggy Whip Chat for Server Version 1.0, Buggy Whip Chat for Server Version 2.0, etc. This allows you to have customized maintenance releases inside of each API version, but make a clean cutoff on the functionality axis.

There are a few problems with this technique, alas. First off, you’ve now shifted the responsibility of applying conditionalization logic on to the end user. They may have no idea what version of the backend software they are connecting. This means that their IT department is going to have to communicate this information to the users, and then update the information if they ever upgrade their server software.

More alarmingly, you’re now potentially spamming the App Store with multiple versions of the same product. How many versions of the same app will Apple allow before they pull the plug, perhaps without notice? It took a trip to WWDC and a one-on-one with senior management of the App Store to get an answer for my company; you may not have the time and resources to do the same.

Option 4: Exotic Distribution Methods

If the customer base is small enough and the revenue from the app high enough, you might consider doing a custom Enterprise version of the app for each customer. In other words, have each customer apply for an Enterprise provisioning certificate, send it to you, and use it to compile a customer version of the app that the customer can have their employees directly download.

Another alternative is to use a boutique app store. It isn’t well advertised, but Apple actually has a spin-off company called Apperian, which allows enterprises to create private-label app stores. It still requires an enterprise-provisioned application, but it provides a more App Store feeling experience.

Both of these strategies allow tight control of which application version will be associated with which server backend, but at the cost of having to provide concierge-level support to the customer base. This may be practical if you have a small customer base with lots of users in each one, but fails badly if you have hundreds or thousands of customers.

Option 5: The Swiss Army App

What we’d really like to have happen is that the application would contact the server, and download the appropriate version of the application from there. But Apple’s T&Cs prohibit the downloading of binary code into applications, so you’re out of luck there. Apple does allow you to download scripting code, so if you can make your app work with something like LUA or JavaScript, you may have an out, although it’s unlikely.

There’s one final approach you can try to crack this nut. If you’re willing to have your code base and binary size swell linearly with the number of API versions you support, you can duplicate your code base every time you spin off a new server version, change all the class names to have the new server version appended to the end, and then have your initial startup code choose which version of the application to run. In other words, you have a single application which is really multiple applications wrapped together with a crunchy shell. Assuming that nothing from one version steps on another version’s toes, that the binary size doesn’t get out of hand, and that you can manage any shared resource issues correctly, this may be the easier solution to swallow.

Welcome to the Club, We Have Jackets

We’ve come to the end of our Enterprise journey (hopefully not a five-year mission, at least for the first release...). By now, I hope you have a proper respect for the challenges that enterprise developers in the Apple world face, but haven’t been scared off from proceeding further. There is no question that Apple has made enterprise iOS applications a difficult product to produce, but it can be done, and done well.

The good news is that all signs point to better sailing ahead. Apple continues to add features to the SDK and the marketplace that make it easier to develop and distribute iOS application to enterprise customers. There is even hope that we may see direct B2B distribution capabilities some day—the launch of the volume licensing program is a clear indicator of that.

So in conclusion, and to paraphrase Mary Schmich’s famous Chicago Tribune column, push the bounds of the App Store, but don’t let it get you banned. Fight non-applicable corporate policies, but don’t let it get you fired. And remember to wear sunscreen.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset