Search code examples
swiftmacostestingcloudkit

CloudKit sync testing with sandbox users


I'm creating a Mac app that has a non-renewing subscription as an in-app purchase. I want to sync this data to the cloud for the following reasons:

  • I want the user to be able to use the app on all their Macs
  • The in-app purchase enables a widget, so that widget needs to access this data.
  • By Apple's documentation the restoration of non-renewing subscriptions has to be handled by the app by some kind of registration / cloud sync.

So I decided to implement a CloudKit sync to store the following data:

  • Which IAP product did the user purchase (currently only one value, but might change in the future)
  • When did the purchase occur.

Here's what I'm doing now when a user makes an in-app purchase:

  1. I validate the receipt
  2. If I find any IAP data, I sync that to CloudKit
  3. I use a function to fetch the purchase data from CloudKit for the said widget

Question 1: As far as I can tell all the in-app purchases are contained in the receipt file, even after removing and restoring it. I could be using this, however the documentation clearly says I shouldn't. Even the forums are not certain about it... What do you think?

Question 2: While testing the app with multiple sandbox users I noticed that no matter which sandbox user I use to make the purchase, the currently logged in iCloud account (my personal account) gets the receipt data synced to CloudKit. Why isn't the purchaser (App Store) user getting the data to their private cloud database? How can I test that everything works fine? Do I have to log out of my iCloud account to make this work?

Thank you for your time :)


Solution

  • Question 1: Using the App Receipt to restore non-renewable subscriptions

    From Apple's Documentation:

    Apple's documentation on whether an in-app purchase of a non-renewing subscription remains in the receipt has contradictory answers:

    Yes (retrieved 2016-05-11):

    Table 1-2 Comparison of subscription types

    Subscription type       Auto-renewable   Non-renewing    Free
    Users can buy           Multiple times   Multiple times  Once
    Appears in the receipt  Always           Always          Always
    Synced across devices   By the system    By your app     By the system
    Restored                By the system    By your app     By the system
    

    No (retrieved 2016-05-11):

    The in-app purchase receipt for a consumable product or non-renewing subscription is added to the receipt when the purchase is made. It is kept in the receipt until your app finishes that transaction. After that point, it is removed from the receipt the next time the receipt is updated—for example, when the user makes another purchase or if your app explicitly refreshes the receipt.

    From Apple's Developer Forums:

    In a thread reporting the temporary (now fixed) loss of non-renewable subscriptions from the app receipt, an Apple Developer Technical Support engineer said:

    I've queried the iTunes Production Support engineer who made the change - The "fix" to provide the history of non-renewing subscriptions in the application receipt is permanent. My interpretation is that permament means that if we make a change, we'll announce the change at a Developer Conference and announce the function to be deprecated for a period of time.

    With regards to using iCloud as a means to restore non-renewing subscriptions, I've heard from my App Review contact - an application "can use iCloud to track the non-renewing subscriptions (NRS) but it can’t force the user to login prior to making the purchase. It has to be optional - that can can alert the user that iCloud is required to access the NRS content from their other iOS devices - and providing a way to register later, if users wish to have access to this content at a later time."

    Source: https://forums.developer.apple.com/thread/22345#79067

    You could attempt refreshing the app receipt to restore the non-renewable subscriptions, but it has broken before, the documentation isn't clear, and there have been past reports of App Review rejecting applications that try this method.


    Question 2:

    CloudKit always uses the current iCloud account under Settings > iCloud.

    App Store purchases use the Apple ID configured in Settings > iTunes & App Store.

    The user may be signed into the same Apple ID for both iCloud & iTunes, but there is no guarantee. These are two entirely separate settings.