SwiftyStoreKit: Purchasing triggers callback in AppDelegate

675 Views Asked by At

I am implementing SwiftyStoreKit to help with In-App Purchases on iOS. I have a server that is setup to validate receipts, so what I'm trying to accomplish is:

  1. User taps to buy IAP product
  2. If success, receipt is fetched and sent to server for validation
  3. If success, IAP product transaction is set to finish
  4. Update UI.

After the user taps purchase, a function similar to this runs:

func purchase(productId: String) {

    SwiftyStoreKit.purchaseProduct(productId, quantity: 1, atomically: false) { result in

        switch result {

        case .success(let product):

            self.validateReceiptOnServer() { (success) in

                if product.needsFinishTransaction {
                    SwiftyStoreKit.finishTransaction(product.transaction)
                }

                if success {
                    self.updateUI()
                }
                else {
                    self.showError()
                }
            }

        case .error(let error):
            self.showError()
        }
    }
}

SwiftyStoreKit also provides a method that is supposed to be called when the app first launches. This is also stated in the Apple docs. For me, the function looks something like this:

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    SwiftyStoreKit.completeTransactions(atomically: false) { purchases in

        for purchase in purchases {

            switch purchase.transaction.transactionState {

            case .purchased:

                self.validateReceiptOnServer() { (result) in

                    if purchase.needsFinishTransaction {
                        SwiftyStoreKit.finishTransaction(purchase.transaction)
                    }
                    switch result {
                    case .success: print("success validating receipt")
                    case .failure: print("failure validating receipt")
                    } 
                }

            case .restored:

                if purchase.needsFinishTransaction {
                    SwiftyStoreKit.finishTransaction(purchase.transaction)
                }

            case .failed, .purchasing, .deferred: break
            @unknown default: break
            }
        }
    }
    return true
}

For normal, uninterrupted purchases this setup seems to work fine. My problem is that when testing interrupted purchases, after calling SwiftyStoreKit.purchaseProduct, the callback for SwiftyStoreKit.completeTransactions in didFinishLaunchingWithOptions is somehow triggered instead of the purchase callback. I expect this isn't intended, as it makes continuing on with the code in the file that triggered the purchase really cumbersome.

0

There are 0 best solutions below