Update In-App Purchase Failed Transaction Code for Swift 2.2.

As a result of the latest release of Swift 2.2, code to handle a failed transaction of an In-App Purchase (IAP) requires an update.

BACKGROUND

A StoreKit Payment Transaction Observer Delegate implements the SKPaymentTransactionObserver protocol. Method paymentQueue(:updatedTransactions:) is a method in the Protocol that gets called by the payment queue to notify the observer (specifically, the StoreKit Payment Transaction Observer Delegate) that one or more transactions have been updated. In other words, if an in-app purchase is completed, restored because it was previously purchased, or failed because the user does not have purchase authorization, then the delegate that is supposed to do something in response to any of these events must do so. The code to implement the response might look like this:

  public func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
    for transaction in transactions {
      switch (transaction.transactionState) {
      case .Purchased:
        completeTransaction(transaction)
        break
      case .Failed:
        failedTransaction(transaction)
        break
      case .Restored:
        restoreTransaction(transaction)
        break
      case .Deferred:
        break
      case .Purchasing:
        break
      }
    }
  }

WHERE THE CODE CHANGE IS NEEDED

The update to Swift 2.2 affects helper method, failedTransaction(_:).

  private func failedTransaction(transaction: SKPaymentTransaction) {
    
    print("failedTransaction...")
    
    if transaction.error?.code != SKErrorPaymentCancelled {
      // The error was something other than the user cancelling the transaction.

      print("Transaction Error: \(transaction.error?.localizedDescription)")
    }
    
    SKPaymentQueue.defaultQueue().finishTransaction(transaction)
  }

After updating Xcode to version 7.3, the following compiler error appears in failedTransaction(_:).

Failed Transaction Compiler Error 2016-03-24 at 5.14.12 PM

The error

Use of unresolved identifier ‘SKErrorPaymentCancelled’

stems from the fact that error codes for the Store Kit error domain have been changed in Swift 2.2. Both the Swift and Objective-C error codes used to be defined as:

enum {
SKErrorUnknown,
SKErrorClientInvalid,
SKErrorPaymentCancelled,
SKErrorPaymentInvalid,
SKErrorPaymentNotAllowed,
SKErrorStoreProductNotAvailable,
SKErrorCloudServicePermissionDenied,
SKErrorCloudServiceNetworkConnectionFailed 
};

In Swift 2.2, the enumeration for the error codes is now defined as:

enum SKErrorCode : Int {
    case Unknown
    case ClientInvalid
    case PaymentCancelled
    case PaymentInvalid
    case PaymentNotAllowed
    case StoreProductNotAvailable
    case CloudServicePermissionDenied
    case CloudServiceNetworkConnectionFailed
}

Also note the change in type of SKErrorCode to Int.

THE FIX

Therefore, the if statement needs to be changed to:

if transaction.error!.code != SKErrorCode.PaymentCancelled.rawValue {

Now you can get back to having successful failed transactions!

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *