0
votes

I am developing an iOS app. It will have non-consumable in-app purchases.

Q1. Let's say that a user is logged in on their iPad or iPhone to "iTunes & App Store" with "account1", then purchases the in-app purchase, and then logs out of "iTunes & App Store". Then they return to the app.

Should their in-app purchase still be present? Not will it, but should it?

If not, my questions are answered. On the other hand, let's say it should be present. Then I have a follow-up question.

Q2. After following all the above-mentioned steps, the same user logs in to "iTunes & App Store" with a different account, "account2". Should the in-app purchases they made with "account1" still be present while logged in as "account2"?

If you can enhance your own clear and succinct answer with an official statement from Apple, that would be awesome and much more likely to be marked as the solution! If not, thanks in advance for your personal thoughts, ideas, and opinions regarding the best user experience... if Apple doesn't have a clear position on this, then whoever makes the best case will have their answer marked as the solution.

2

2 Answers

1
votes

Certainly an unusual case for two users to enter their App Store credentials on the same device. That said, the closest I can see to Apple having something to say about this is:

"Non-consumable products. Items that remain available to the user indefinitely on all of the user’s devices. They’re made available to all of the user’s devices. Examples include content, such as books and game levels, and additional app functionality."

If you take this literally, and if you consider the device still being the same user's even if they have logged out, then I suppose you should make sure you award the non-consumable to the new user as well.

In my experience, many apps store locally when an IAP has been purchased so if the app has not been deleted, any user will see the unlocked content. Your app won't necessarily know that a new iTunes user is using the app, so it would be hard to detect that a new user was using it and revoke the content.

Additionally if you didn't want two users to potentially share a purchase, it would make more sense, in my opinion, to make the purchase a consumable and enforce some sort of log-in mechanism in your app such that it is credited to an individual authenticated account.

1
votes

Purchases are literally stored in a file in the app bundle on the device. The path or url to the file can be accessed using appStoreReceiptURL. This documentation states:

In OS X, if the appStoreReceiptURL method is not available (on older systems), you can fall back to a hardcoded path. The receipt’s path is /Contents/_MASReceipt/receipt inside the app bundle.

While this is quote specifically mentions OS X, the same is true for iOS with the exception that the result is a localised app url. To support this further, the documentation for NsBundle (which is what appStoreReceiptURL returns) states:

An NSBundle object helps you access the code and resources in a bundle directory on disk.

So with this understanding, we can conclude that purchases are not stateless. They remain within the context of the app. If a user signs out of iTunes, the file isn't deleted.

If an app listens to the SKPaymentQueue, new transactions will come in from time-to-time, particularly when a user buys an auto-renewing subscription. If the user is signed out of iTunes they will receive a request to sign in with the account they originally subscribed with in order for the app receive and save the new receipt. But I digress.

By retaining the purchase state in the app, it allows the purchases to be used without an internet connection. Since an offline device can't authenticate with Apple, keeping the purchase state anywhere else would break this functionality. So yeah, it should be present.

As for Q2, the receipt for account1 is replaced with account2 once a transaction for account2 is received. However until account2 has their made first transaction account1's receipt will still be on disk. This can be used as an exploit to share purchases between users and AFAIK, no good solution exists without using your own user accounts. There are a bunch of stack posts describing this problem.

Should it happen? I wish it didn't, but it seems it is an unintended consequence of the stateful design of the purchase receipts.