Last month among all the WWDC hoopla you may have missed a small change that Apple made to its iOS App Store Guidelines (sec 3.1.1):

Non-subscription apps may offer a free time-based trial period before presenting a full unlock option by setting up a Non-Consumable IAP item at Price Tier 0 that follows the naming convention: “XX-day Trial.” Prior to the start of the trial, your app must clearly identify its duration, the content or services that will no longer be accessible when the trial ends, and any downstream charges the user would need to pay for full functionality. Learn more about managing content access and the duration of the trial period using Receipts and Device Check .

Considering that iOS developers have been clamoring for a trialware model for their apps since the App Store debuted ten years ago, I found this addition very intriguing, but not all that clear. For one, the guidelines still say (sec 2.2):

…trial versions of your app don’t belong on the App Store — use TestFlight instead.

Which is it, do you want trial apps or not?

Also, Apple had already silently begun allowing apps to function as trialware provided that they allowed some minimal functionality after the trial period ended. (Some of Omni Group’s apps utilize this model.) Is this new guideline just formalizing that tacit policy, or is it really inviting all-or-none trialware apps into the App Store?

Since, as far as I know, no developer has yet tested this boundary, I thought it would be interesting to try it.

Tempi

We’ve tried a couple of different payment models with our app Tempi, which helps musicians with their rhythm. First it was freemium with in-app purchases, then it was paid upfront. In terms of revenue, both of these strategies performed about the same but I always thought a classic trialware model would be a better fit.

To be honest, I was pretty sure Apple would reject an all-or-none trialware app so I didn’t want to spend much time on the design, however an important implementation question needed answering: How should an app keep track of when a user’s trial period started? There are several options here each with some pros & cons.

Tier 0 IAP + DeviceCheck

In the paragraph from Apple’s new guidelines, they explicitly advise that we use a “tier 0” (i.e. free) IAP that we require the user to “buy” to start the trial period. They also call out DeviceCheck, an API new to iOS 11 which stores just 2 bits of information. Presumably they mean that we could use one of those bits to store whether the app is unlocked or not across app installs.

I don’t like this approach. First, I think having to tap a Buy button for an IAP product that costs $0.00 would be confusing to a substantial percentage of users. And what if you wanted to reset the trial for all users that had already exceeded the trial period, say, because you added some major new features? You’d need to make a whole new IAP product to do that. Lastly, DeviceCheck is only available in iOS 11 forward and requires you to use JSON Web Tokens in conjunction with a REST API, which is a lot of new infrastructure you’d need to bring up if you don’t already have it.

UserDefaults

It’s a bit naive but you could just store the date that the user started their trial in UserDefaults. It’s trivial to do and would allow you to restart the trial at any time. The obvious downside is that any user could restart their trial period simply by deleting and reinstalling the app.

Keychain

It’s a little-known fact that when an app stores information in the user’s keychain, that information is persistent even across app reinstalls.¹ Further, by default these items are stored in such a way that they don’t sync to the Mac via keychain syncing, making it nearly impossible for a user to remove them and circumvent the trial period. Obviously this mechanism shouldn’t be abused, but I think it’s a perfect solution for storing the trial start date. If we ever want to reset the trial period, we can either remove the existing item or choose a new item name.