"Restore Transactions" Button behavior when there is nothing to restore

Viewed 6179

As discussed in this question and everywhere else, Apple now requires apps to include a means for the user to restore completed transactions for In App Purchases.

I'm all for this. The first version of my app somehow made it past review without it (I wasn't aware of this rule at the time, and/or it wasn't being enforced yet), but then I started receiving lots of e-mails from users asking about missing content (there is the Data Storage Guidelines too, and the heavy, downloadable contents aren't backed up).

So let's say I include a 'restore' button somewhere in my UI, that when tapped calls:

[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];

So far, so good. The user is prompted his AppleID and/or password, and the restoring process begins.

The problem I have is: If there is no transactions to restore, after the AppleID prompt essentially nothing happens in my app, and that may be confusing to the user or make the app look unresponsive or broken.

I would like to be able to display an alert view along the lines of "All purchases are up to date" or something.

Is there anything I can do in my Transaction Observer code to detect this case?

Does anybody think it would be a bad design, UX-wise?

4 Answers

This is still an issue in the latest SDK / xCode 8.0, Swift 3 - if a user who hasn't made any purchases attempts to 'restore', the following method:

SKPaymentQueue.default().restoreCompletedTransactions()

does not trigger the usual delegate method that handles purchases / restoring:

paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {...}

Interestingly, the method that probably should catch the error is also NOT called:

func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error){...}

And instead, the optional method is triggered, as if the restore worked fine:

func paymentQueueRestoreCompletedTransactionsFinished()

This can cause the app to look like it is hanging / not doing anything.

As discussed in the other answers, the cause of this is that the SKPaymentQueue doesn't contain any transactions.

in Swift, this problem can be overcome by using the following:

//Optional Method.
func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue)
{

    let transactionCount = queue.transactions.count

    if transactionCount == 0
    {
        print("No previous transactions found")

        //You can add some method to update your UI, indicating this is the problem e.g. use notification centre:
        NotificationCenter.default.post(name: "restoreFailedNoPrevIAP", object: nil)

    }

}

Importantly, if a user has made previous purchases, the transaction queue will not be empty, hence updateTransaction delegate method will be called, and will process the restore request normally.

Related