[ This ended up being a fairly long and somewhat technical post. I edited it down as best I could, but I think it’s an important topic in the iPhone world and something that has to be laid out in its entirety. I suspect it won’t be of much interest unless you’re an iPhone app developer, a highly technical end-user, or a masochist masquerading as a layperson. You have been warned. – Ed.]
The news dropped like a bombshell on the iPhone developer community yesterday: Apple is now allowing In App Purchasing in free applications. Hip Hip Hooray!
But wait. What does that mean?
I won’t repeat what I’ve already said in a previous post but the upshot is it’s now possible to ship a free application on the iPhone appstore then ask the customer to purchase an ‘unlock’ token once they’re done evaluating it. The common consensus (as much as what is said on blogs, mailing lists, and twitter can be considered so) in the developer community is that it’s a positive move. Marco Arment (the developer of Instapaper) called it a “… great move for both users and developers.”
With this seemingly small change in policy consumers can (finally) try out an app before they have to pay for it. No more buying an app then realizing it doesn’t work and getting stuck with a dud. The immediate effect will most likely be fewer impulse sales–which means lower short-term revenue–but in the long-term users are more likely to be happy customers instead of accidental ones.
It’ll also mean that app developers should be able to increase their asking price for well-made apps, because users will have had a chance to take it out for a test run. On the other hand, there’s no guarantee this will end up increasing per-app revenue given the low conversion ratio from free to for-pay apps. In fact, I’d strongly question the logic of $0.99 apps even bothering to offer an evaluation version. All those impulse and let’s try this purchases probably account for a more substantial portion of sales than most developers care to admit.
But the initial developer reaction seems to be positive. Most indy developers in it for the long run would rather have fewer happy customers vs. a lot of unhappy ones.
First, let’s take a little detour and define what we actually mean by an evaluation app.
In the regular computer world (versus, you know, the iPhone Candyland) a developer creates an application then offers it to the user for evaluation in one of two possible ways:
- Degraded mode: this is where the application has some of its features disabled, for example, no saving or only printing with a watermark. The user gets to experience what the app does, but only up to a point. How much functionality is included is up to the developer but it’s in their interest to allow as much as possible to make the sale without giving up too much.
- Time-limited mode: this is where the application is fully functional for a limited amount of time (usually two weeks to 30 days). After that either the user buys the app or it stops working. A slight variation is where the app reverts to degraded mode when the eval clock runs out.
The main difference between a Time-Limited and a Degraded app is what the developer allows the user to experience during that period of time. That’s an important distinction because the end-user experience was noted by Apple as the main reason they initially didn’t allow In App Purchasing in free apps. The reasoning was that a user should not be told an application is free, then be forced to pay for it. But it appears that concerns for application piracy and loud complaints from developers have overridden those worries. But the problem is still valid. Hopefully Apple will make changes to the Appstore to better communicate the actual fully unlocked price to avoid end-user confusion.
There’s also a subtle issues unique to the Time-limited app on the desktop and that is what to do when the user tries to get around the evaluation restrictions — ostensibly to keep using the application in full evaluation mode ad infinitum without having to pay. The two most common methods are settings back the system clock (to make the app think the eval time hasn’t run out), or to uninstall then reinstall an app to reset the meter.
The solution to both of these problems is fairly simple: the app can write an already run token and periodically save a time-stamp in such a way that persists beyond an application getting uninstalled. Then it’s fairly easy to detect if the clock has moved back or if an app has been reinstalled.
But that’s the desktop. What about the iPhone? The problems are the same. Some users may be tempted to keep an eval app (especially a high-priced one) running. Can the clock reset trick work? Yes, it can. Most users leave their phone’s clock in its default auto-update mode so they can use their phone to keep track of time. But it’s fairly easy to reset it manually. All you have to do is run the Settings application, go under General tab and disable Set Automatically then set the clock to whatever date and time you want. The down-side to this is that so much of what you do on a typical iPhone relies on the system clock so it’s unlikely someone will be willing to put up with having a constantly skewed clock on their phone for the sake of just one application. But you never know.
What about the delete/reinstall method? On the iPhone, once an app has been deleted all associated files are also removed so there would have to be a way to save a persistent token that outlasts the app install-delete cycle. On the iPhone, unlike the Mac, no such place exists. The app developer could always save the unique device ID (UDID) of the phone on a server, but the Apple developer license explicitly forbids saving private user data off the phone. Does the UDID count as private data? It certainly is unique. We’ll have to see. But at the very least, it means each developer has to maintain server infrastructure to track this sort of thing.
So as it currently stands it’s too easy for a user to simply remove and reinstall an app or to fiddle with their clock and continue using an app in its fully-functional eval mode. I’m pretty sure this isn’t what Apple had in mind when allowing In App purchases.
That leaves Degraded mode. This means that the application the user would download from the Appstore for evaluation wouldn’t be the full version. In an earlier draft of the developer license agreement shipping this type of app was explicitly forbidden. In the newly revised version, well, it’s not so clear. In Attachment 2.4 it is clearly stated that:
2.4 You may not use the In App Purchase API to send any software updates to Your Application or otherwise add any additional executable code to Your Application. An In App Purchase item must either already exist in Your Application waiting to be unlocked, be streamed to Your Application after the purchase transaction has been completed, or be downloaded to Your Application solely as data after the purchase transaction has been completed.
This means that the full application functionality must be installed on the phone–no way to send up updated binaries. So all the code is there ready to go but a little key is needed to unlock it. On the desktop this type of app is derisively (and deservedly) called crippleware.
In other words, as of today, what Apple is allowing app developers to ship is crippleware for your iPhone. I could be wrong on this but this clearly falls under the category of Unintended Consequences.
The user plays with the eval app for 30 days (or so) then purchases the unlock token via In App Purchasing. The token is saved on the system so from now on the app launches in its unlocked state. But what form is that token going to take and where is it going to be stored? Given the current sandboxed architecture of the iPhone app, There are two places where an application can actually write data:
- The filesystem under the application’s Documents folder. This can be a text file, a user preference plist, a record in a SQLite database, or a CoreData store.
- In the keychain as a secure key/value data item.
Apple has intentionally stayed out of the business of what shape or form this add-on functionality or unlocking feature should take. It’s up to the individual developers to decide but odds are it will be one of these two methods.
Trouble is both these methods will actually make it easier for apps to get pirated.
On a regular iPhone no app can cross the sandbox line and access another app’s private data. But on a jailbroken phone no such lines exist. So a few minutes after the app is installed on a jailbroken phone, that special token can be easily extracted and plastered all over the internet. Now you don’t even need to resort to apps like Crackulous to get your free fully-functional apps.
The solution is for each individual app developer to implement tighter security around the application, by implementing secure unlock tokens, perhaps even tied to a specific handset so even if they’re removed from a single phone they won’t be usable on any other phone. But that involves knowing quite a bit about the pros and cons of cryptography and your typical iPhone app developer is not going to have the time and patience to implement anything like that.
So they’ll take the quick and expedient way–they’ll offer crippleware and save the token into a user preference plist or keychain — and hope and pray nobody bothers looking there. Or they’ll sign up with outfits like Urban Airship, iLime, or Push.IO to take care of it for them for a fee.
But this doesn’t mask the fact that with no Apple-defined standard, it’s going to be a free-for-all.
The final bit of ugliness heading our way has to do with user reviews. In the early days of the AppStore anyone could leave reviews — regardless of whether they had bought the app or not. This rendered the system useless since most of the initial write-ups consisted of, um, price-resistant customers (endearingly called freetards by developers) complaining about the price, no matter how low. It didn’t take long for Apple to clamp down on this by requiring only those who had actually purchased an app to review them. This substantially cut down on the noise and helped keep Appstore reviews an important part of the consumer decision-making process.
But now with the advent of free evaluation apps we’re going to go back to the halcyon days of price-gripes, where a user will download the free version of the app, take a look at the price for obtaining the unlock token and submit a 1-star review, complaining about, yes you got it, the price of the app. The current AppStore filter will not work since they’ve officially downloaded the app and technically count as having purchased the app.
One step forward. Two steps back. In other words, it’s going to get ugly. Again.
You’ve been so patient. I won’t keep you waiting. Here are a few steps Apple needs to take for this eval system to work:
- Offer a simple, official API for supporting both Time-limited and Degraded evaluations. This means associating some application metadata with each app when it’s installed and forcing Springboard (the iPhone application launcher) to honor these settings before running the application. Springboard already does this when it installs an app–that’s how the App Store application updated can tell what version you’re running vs. what’s on the store.
To prevent the remove-reinstall workaround, there has to be a way to save some information that lives outside the sandbox and survives application removal. This can be on the phone or on a server. Again, Apple already does both these things. It saves data to the system keychain and it keeps track of what apps you’ve “bought” on the AppStore (so when you go reinstall, it knows not to charge you twice). So it would be easy for them to let the app-developer mark the application as eval, whether Time-limited (and or how long) or Degraded.
I would even argue that anything having to do with application installation or unlocking belongs in the AppStore/OS domain, not left to individual applications. Anything having to do with In App purchasing of extra grenade-launchers, leave it up to the app.
- Far, far more importantly (and I can’t emphasize this enough) Apple should provide a simple API for an application to verify that the current user has purchased the app. This will do far more to cut down on application piracy than allowing free evals. The app developer can periodically and at random times invoke this API and ask two simple questions: Has the current user bought this app? and When?.
A developer would be wise to sprinkle calls to the API throughout the app. Yes, the application binary can be patched and the API call removed, but that’s a higher wall for your typical cracker to climb than simply modifying a single entry in a text file.
- The last thing Apple could to do help eval/buy apps a success is implement a policy where only users who had purchased the unlock token would be allowed to post comment and reviews on the AppStore. Let’s maintain the status quo instead of taking a step back. The problem, however, is given the totally unstructured way the current In App Purchase model is implemented, there is no viable way in which an extra rocket-launcher token can be distinguished from an unlock application token.
I would argue that unlocking eval applications, verifying proper ownership, and restricting access to the review system should be the responsibility of the entities that control application installation and launching–i.e., the operating system and iTunes–instead of individual developers. But in lieu of that, Apple should give developer tools to properly implement an evaluation system that welcomes legitimate users and cuts back on potential abuse.
In the absence of a network connection, the default would be to let the application run a limited number of runs (until the user gets back to the network).
But what about the When? question? The answer would be a timestamp indicating when the user paid for the app. That piece of information is important to app-developers who currently have multiple free/pay versions of applications on the appstore (or who want to continue using that model). For these folks to move from a free/pro model to an eval/buy model means that their end users would have to obtain a new version of their application. There would have to be a way to tell whether the current user paid for the full version of the app during the pre-eval period and not force them to go through the whole purchase cycle again.
I should also emphasize that with this API the application will never have to be given access to any private user-credentials. Something like the following added to UIApplication will work wonders to ward off app piracy:
+ BOOL isAppPurchased; + NSDate* dateOfPurchase;
In summary: The In App Purchase mechanism is a great system for supporting application add-ons. But it’s wholly unsuited for supporting eval applications and does nothing to fight application piracy. Having properly implemented eval apps is important to the future of this ecosystem. Apple shouldn’t leave it up to individual developers to figure out how to get there. It should be part of the core functionality of the operating system.