SwiftyStoreKit: Multiple occurrences of IAP not passing and restore returning: Cannot connect to iTunes Store

Platform

  • iOS
  • macOS
  • tvOS

In app purchase type

  • Consumable
  • Non-consumable
  • Auto-Renewable Subscription
  • Non-Renewing Subscription

Environment

  • Sandbox
  • Production

Version

running on swift-2.3 branch

Related issues

#140 but contrary to that person I cannot reproduce myself this error. But it happens to about 25% of my transactions which is a big deal at the moment. (Last week on 50 transactions I got about 9 of them who got that error).

Report

Issue summary

Multiple customers are emailing us about not being able to purchase our IAP for our PRO version.

One said “i buyed the pro version, but the ads still on. And App says nothing to restore.”

Basically, we have a buy pro version in the app’s preferences. When they press on it a call to SwiftyStoreKit.purchaseProduct is done.

When he tries to restore, results.restoreFailedProducts = [(Error Domain=SKErrorDomain Code=2 "Cannot connect to iTunes Store" UserInfo={NSLocalizedDescription=Cannot connect to iTunes Store}, nil)]

What did you expect to happen

Transactions should pass and when they do they should and result in errors they should at least be restorable if the initial transaction went okay.

What happened instead

Purchase never seems to pass. Restore returns a cannot connect to itunes store error. Leaving the customer without any way of getting the product.


Just for more information, I added both my purchase and restore methods here. Feel free to ask for more details. Please don’t mind the debug calls.

static func purchasePro() {
    SwiftyStoreKit.purchaseProduct(ProProductIdentifier) { result in
        switch result {
        case .Success(let productId):
            self.hasPurchasedPro()
            // reloading UI to get rid of ads
            self.reloadAdUI()
            if Consts.DebugPurchases {
                self.notificationHandler.displayAlert("Purchase Success", message: "\(productId)", type: .Success)
            } else {
                // logging event
                LoggingHandler.reportEvent("PurchaseProSuccess", customData: ["productId": "\(productId)"])
            }
        case .Error(let error):
            if Consts.DebugPurchases {
                self.notificationHandler.displayAlert("Purchase Failed", message: "\(error)", type: .Danger)
            } else {
                // logging event
                LoggingHandler.reportEvent("PurchaseProFailed", customData: ["error": "\(error)"])
            }
        }
    }
}

static func restorePurchase(silenced: Bool) {
    // trying to restore something
    SwiftyStoreKit.restorePurchases() { results in
        if results.restoreFailedProducts.count > 0 {
            // if debug, display response
            if Consts.DebugPurchases {
                self.notificationHandler.displayAlert("Restore Failed", message: "\(results.restoreFailedProducts)", type: .Danger)
            } else {
                // silence this notification and logging
                if !silenced {
                    // contact support if this seems wrong
                    self.notificationHandler.displayAlert("restore_error".localized(), message: "nothing_to_restore_is_it_wrong".localized(), type: .Danger)
                    // logging event
                    LoggingHandler.reportEvent("RestoreFailed", customData: ["restoreFailedProducts": "\(results.restoreFailedProducts)"])
                }
            }
        } else if results.restoredProductIds.count > 0 {
            // mark user as pro and reload ui
            self.hasPurchasedPro()
            self.reloadAdUI()
            // if debug, display response
            if Consts.DebugPurchases {
                self.notificationHandler.displayAlert("Restore Success", message: "\(results.restoredProductIds)", type: .Success)
            } else {
                // logging event
                LoggingHandler.reportEvent("RestoreSuccess", customData: ["restoredProductIds": "\(results.restoredProductIds)"])
            }
        } else {
            // silence this notification
            if !silenced {
                self.notificationHandler.displayAlert("restore_error".localized(), message: "nothing_to_restore".localized(), type: .Danger)
            }
        }
    }
}

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Comments: 19 (4 by maintainers)

Most upvoted comments

Just to follow up on my original report: we eventually had to ‘fix’ this issue by leaving out the SwiftyStoreKit alltogether. A fresh plain StoreKit implementation did the trick, and it wasn’t very hard (just 1 day of refactoring).

I can confirm same error as @Randam: state: failed, date: nil Error Domain=SKErrorDomain Code=0 “Cannot connect to iTunes Store” UserInfo={NSLocalizedDescription=Cannot connect to iTunes Store}

We are experiencing the same issue mentioned by @tbergeron. For over a month now a large number of purchases are failing in our app. All return a variation on this error, with code=0 or code=2:

SKError(_nsError: Error Domain=SKErrorDomain Code=0 “Cannot connect to iTunes Store”

We have also upgraded swift and released a new version earlier today. Only to discover that the same problem is still present.