4

I have a few in-app purchases. However, I read I need to provide a way to restore them in case that they delete my application by accident. They are nonconsumable items, like skins and textures. I was reading a tutorial on this site: https://code.tutsplus.com/tutorials/in-app-purchase-tutorial-with-swift-3-ios-sdk--cms-27595

However, their explanation of restoring transactions confused me. They did this:

@IBAction func restorePurchaseButt(_ sender: Any) {
SKPaymentQueue.default().add(self)
SKPaymentQueue.default().restoreCompletedTransactions()
}

func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
nonConsumablePurchaseMade = true
UserDefaults.standard.set(nonConsumablePurchaseMade, forKey: "nonConsumablePurchaseMade")

UIAlertView(title: "IAP Tutorial",
message: "You've successfully restored your purchase!",
delegate: nil, cancelButtonTitle: "OK").show()
}

However, they never showed me where they actually used the paymentQueueRestoreCompletedTransactionsFinished(). I understand they are using the restorePurchaseButt() to restore the purchases. However, I don't understand both of these methods.

SKPaymentQueue.default().add(self)
SKPaymentQueue.default().restoreCompletedTransactions()

How does that snippet of code even check if the user made the purchase? I don't see any if statements. And I assumed maybe restoreCompletedTransactions() triggers paymentQueueRestoreCompletedTransactionsFinished(), but I am not sure? However, even if it does, how does paymentQueueRestoreCompletedTransactionsFinished() check if the player made those transactions or not? How does it now what in-app purchases to restore when there are multiple?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Pablo
  • 1,302
  • 1
  • 16
  • 35

2 Answers2

16

As you did in the button to restore, you need to add:

SKPaymentQueue.default().add(self)
SKPaymentQueue.default().restoreCompletedTransactions()

Then you also need to add this function with the different in-app purchases you have in iTunesConnect. Change "ProductID" for case to be a product ID from iTunesConnect and add as many cases as you have in-app purchases.

func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
    for transaction in queue.transactions {
        let t: SKPaymentTransaction = transaction
        let prodID = t.payment.productIdentifier as String

        switch prodID {
        case "ProductID1":
            // implement the given in-app purchase as if it were bought
        case "ProductID2":
            // implement the given in-app purchase as if it were bought
        default:
            print("iap not found")
        }
    }
}

To answer your questions: It looks like this particular tutorial you were following was focusing on teaching you the overarching ideas of in-app purchases and used their example purchase rather than code that can be used for multiple products.

Apple checks if the item was previously purchased through the restoreCompletedTransactions() function that you call when the button. This is part of the StoreKit framework that Apple provides. It automatically triggers the paymentQueueRestoreCompletedTransactionsFinished() function once it has checked. With the code I provide above, it performs different code depending on which purchases it found or prints to the console if it did not find the product to restore.

Olivia Brown
  • 266
  • 1
  • 10
  • This is actually the solution. I have been wondering for this solution. Thanks Olivia. Voting Up! – Nauman Aslam Feb 07 '18 at 15:15
  • Suppose I have 4 products to purchase and for that I have given 4' Buy' buttons. Do I need to provide 4 ''Restore' buttons (beside every 'Buy' button)?. Or Showing only 1 Restore Button would work? – Sheetal Shinde Jan 13 '21 at 18:08
1

I can't speak for the tutorial but I would say that handling purchases is a very sensitive thing. You could definitely implement it yourself but I would urge you to maybe try using a library instead. I use SwiftyStoreKit and It handles a lot of those edge cases and nuances that occur. https://github.com/bizz84/SwiftyStoreKit

From there when you restore you of course now have to check which products were restored and proceed from there

TNguyen
  • 1,041
  • 9
  • 24