Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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?

like image 895
Nicolas Miari Avatar asked Jul 13 '12 10:07

Nicolas Miari


People also ask

What does the Restore Purchases button do in games?

Restoring purchases prevents you from losing all the things that have been purchased on the old devices.

What does restore mean for in-app purchases?

Answer: A: Answer: A: It means that if you made an in-app purchase in that game but on another device you can restore those purchases with your apple ID log in credentials without having to pay again.

What happens if you press Restore purchases?

If you have multiple devices signed in to the same ‌Apple ID, Restore Purchase will allow you to transfer your in-app purchases to your other devices without having to pay again. For example, if you make an in-app purchase inside an app on your iPhone, you may be able to restore that in-app purchase on your iPad.


1 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.

like image 102
nervous-energy Avatar answered Sep 28 '22 22:09

nervous-energy