Hi,
How can I wait until an IAP transaction/restore is finished?
Thanks in advanced.
How can I wait until an IAP transaction/restore is finished?
Thanks in advanced.
Hard to say something concrete and sure without seeing the details, but you may need to change your way of thinking.How can I wait until an IAP transaction/restore is finished?
If you were accustomed to completion handler pattern, it would not be so difficult.
I was not able to find the answer in documentation and when I create a completion handler on skpaymentqueue, it gives me errors for it not conforming to protocols.You will find sample code that explains how to properly use this.
Code Block public func purchase(product: Product, completion: @escaping () -> Void) { guard SKPaymentQueue.canMakePayments() else { return } guard let storeKitProduct = products.first(where: { $0.productIdentifier == product.rawValue }) else { return } Utilities.purchaseFailed = Bool() let paymentRequest = SKPayment(product: storeKitProduct) SKPaymentQueue.default().add(self) SKPaymentQueue.default().add(paymentRequest) completion() } public func restore(completion: @escaping () -> Void) { SKPaymentQueue.default().restoreCompletedTransactions() completion() } func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { transactions.forEach({ transaction in switch transaction.transactionState { case .purchasing: //No op break case .purchased: handlePurchase(transaction.payment.productIdentifier) Utilities.purchaseFailed = false SKPaymentQueue.default().finishTransaction(transaction) break case .failed: Utilities.purchaseFailed = true Utilities.restoredPurchases = false SKPaymentQueue.default().finishTransaction(transaction) break case .restored: print("purchases restored") handlePurchase(transaction.payment.productIdentifier) Utilities.restoredPurchases = true SKPaymentQueue.default().finishTransaction(transaction) break case .deferred: break @unknown default: break } }) } private func handlePurchase(_ id: String) { UserDefaults.standard.setValue(true, forKey: id) print("id = \(id)") if id == "JokesRUs.RemoveAds" { Utilities.ShowAds = false } if id == "JokesRUs.Icons.Summer" { print("summer bought") IconChange.setIconPurchased = true IconChange.summerIconUnlocked = true IconChange.numUnlocked = IconChange.numUnlocked + 1 UserDefaults.standard.setValue(IconChange.numUnlocked + 1, forKey: "numUnlocked") UserDefaults.standard.setValue(true, forKey: "summerIconUnlocked") } if id == "JokesRUs.Icons.Taco" { print("taco bought") IconChange.setIconPurchased = true IconChange.tacoIconUnlocked = true IconChange.numUnlocked = IconChange.numUnlocked + 1 UserDefaults.standard.setValue(IconChange.numUnlocked + 1, forKey: "numUnlocked") UserDefaults.standard.setValue(true, forKey: "tacoIconUnlocked") } if id == "JokesRUs.Icons.Pizza" { print("pizza bought") IconChange.setIconPurchased = true IconChange.pizzaIconUnlocked = true IconChange.numUnlocked = IconChange.numUnlocked + 1 UserDefaults.standard.setValue(IconChange.numUnlocked + 1, forKey: "numUnlocked") UserDefaults.standard.setValue(true, forKey: "pizzaIconUnlocked") } if id == "JokesRUs.Icons.HotDog" { print("hotdog bought") IconChange.setIconPurchased = true IconChange.hotdogIconUnlocked = true IconChange.numUnlocked = IconChange.numUnlocked + 1 UserDefaults.standard.setValue(IconChange.numUnlocked + 1, forKey: "numUnlocked") UserDefaults.standard.setValue(true, forKey: "hotdogIconUnlocked") } if id == "JokesRUs.Icons.Hamburger" { print("hamburger bought") IconChange.setIconPurchased = true IconChange.hamburgerIconUnlocked = true IconChange.numUnlocked = IconChange.numUnlocked + 1 UserDefaults.standard.setValue(IconChange.numUnlocked + 1, forKey: "numUnlocked") UserDefaults.standard.setValue(true, forKey: "hamburgerIconUnlocked") } if id == "JokesRUs.Icons.Doughnut" { print("doughnut bought") IconChange.setIconPurchased = true IconChange.doughnutIconUnlocked = true IconChange.numUnlocked = IconChange.numUnlocked + 1 UserDefaults.standard.setValue(IconChange.numUnlocked + 1, forKey: "numUnlocked") UserDefaults.standard.setValue(true, forKey: "doughnutIconUnlocked") } }
Because you write completion() where it is called too early.The thing is, there is no error, it just calls completion() too early.
Seems I need to repeat, you need to clarify where is the correct placeSo then, how do I write completion in the correct place?
So, where is the place where the transaction has taken place?After the transaction has taken place.