问题
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?
回答1:
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.
回答2:
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
来源:https://stackoverflow.com/questions/45765122/how-to-restore-in-app-purchases-correctly