2

I want to implement annual subscription into my app, and I do it using StoreKit. The problem is, when I tap subscriptionButton. An app throwing an error: 'NSInvalidArgumentException', reason: 'Cannot finish a purchasing transaction'. I was stuck in this place and can't resolve my problem. So, my paymentQueue code looks like that:

func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
    print(transactions)
    for transaction in transactions {
        print(transaction.error ?? "")
        switch transaction.transactionState {
        case .deferred:
            print("deffered")

        case let .failed(err):
            print("failed: \(err)")
        case .purchased:
            let productID = p.productIdentifier
            selectProduct(productID: productID)
        case .purchasing:
            print("purhasing")
            print("produkt name: \(p.localizedTitle)") // after executing this line of code app crashes
        case .restored:
            let productID = p.productIdentifier
            selectProduct(productID: productID)
        }
        queue.finishTransaction(transaction)
    }
}

Do you have any suggestion, how can I fix it?

PiterPan
  • 1,760
  • 2
  • 22
  • 43
  • 1
    You are getting such result because when you purchasing state detected after that "queue.finishTransaction(transaction)" method is executing which stops further process. Add that method specific to ".purchased", ".restored" & ".failed" state only. – Sagar Thummar Jan 12 '17 at 13:09
  • great for your suggestion! it works :) – PiterPan Jan 12 '17 at 17:49

1 Answers1

5

Working solution of this problem in my case is:

func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
    for transaction in transactions {
        print(transaction.error ?? "")
        switch transaction.transactionState {
        case .deferred:
            print("deffered")
            queue.finishTransaction(transaction)
        case let .failed(err):
            print("failed: \(err)")
            queue.finishTransaction(transaction)
        case .purchased:
            let productID = p.productIdentifier
            selectProduct(productID: productID)
            queue.finishTransaction(transaction)
        case .purchasing:
            print("purhasing")
        case .restored:
            let productID = p.productIdentifier
            selectProduct(productID: productID)
            queue.finishTransaction(transaction)
        }
    }
}
PiterPan
  • 1,760
  • 2
  • 22
  • 43
  • `case let .failed(err)` didn't work in my environment. Though I am not sure if it's equivalent, I wrote like the following. ` case .failed: let err = t.error ?? NSError() print("failed: \(err)") ` – ITO Yosei Mar 24 '19 at 00:22