恢复应用内购买时出现 StoreKit 问题

StoreKit problem while restoring In-App Purchase

我试图找到有关 IAP 的教程,我发现:This one

但是当我调用恢复函数时,没有任何反应。我调用的 OnTap 按钮:store.restorePurchase()

extension Store {
    func product(for identifier: String) -> SKProduct? { ...}
    func purchaseProduct (_ product: SKProduct){ ...}
    func restorePurchases() {
        SKPaymentQueue.default().restoreCompletedTransactions()
        print("restore")
    }
}

restore 打印在我的控制台中。这是控制台中唯一打印的内容。但是在上面的代码中,你可以看到.restored:that should print "UserIsPremium"

extension Store : SKPaymentTransactionObserver {
    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions : [SKPaymentTransaction]){
        for transaction in transactions {
            var shouldFinishTransaction = false
            switch transaction.transactionState{
            case .purchased, .restored:
                completedPurchases.append(transaction.payment.productIdentifier)
                print("UserIsPremium")
                shouldFinishTransaction = true
            case .failed:
                print("NotPremium")
                shouldFinishTransaction = true
            case .deferred, .purchasing:
                print("...")
                break
            @unknown default:
                print("unknown")
                break
            }
            if shouldFinishTransaction {
                print("shouldfinish")
                SKPaymentQueue.default().finishTransaction(transaction)
                DispatchQueue.main.async {
                    self.purchaseCompletionHandler?(transaction)
                    self.purchaseCompletionHandler = nil
                }
            }
        }
    }
}

我的 class 商店:

import StoreKit

typealias FetchCompletionHandler = (([SKProduct]) -> Void)
typealias PurchaseCompletionHandler = ((SKPaymentTransaction?) -> Void)

class Store: NSObject, ObservableObject {

@Published var allFullVersion = [FullVersion]()

private let allProductsIdentifiers = Set ([
"ClemPapplis.OrientationEPS.versionFull"
])
private var completedPurchases = [String]() {
    didSet {
        DispatchQueue.main.async{ [weak self] in
            guard let self = self else { return }
            for index in self.allFullVersion.indices {
                if self.completedPurchases.contains(self.allFullVersion[index].id){
                    print("completedPurchases")
                    UserDefaults.standard.setValue(true, forKey: "Premium")
                }
                self.allFullVersion[index].isLocked =
                    !self.completedPurchases.contains(self.allFullVersion[index].id)
            }
        }
    }
}

我使用沙盒测试器。 如果我购买商品,没问题,数据会打印在控制台中。

我是不是忘记了什么?

我已经有几年没有使用 StoreKit 了,但我记得我也有一个关于恢复购买的问题(是的,@ElTomato 是正确的,使用一个单独的案例 - 我很惊讶你的代码实际上构建了)。我发现以下方法有效:

public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
    for transaction:AnyObject in transactions {
        if let trans = transaction as? SKPaymentTransaction {
            switch trans.transactionState {
            case .purchased:
                SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
                delegate.purchaseComplete()
            case .failed:
                SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
            case .restored:
                SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
            default:
                break
            }}}
}
func restorePurchases() {
    SKPaymentQueue.default().add(self)
    SKPaymentQueue.default().restoreCompletedTransactions()
}
public func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
    for _ in queue.transactions {
        alreadyPurchased = true
        delegate.purchasesRestored()
    }
    showAlert("Purchases have been restored.")
}

不用担心 showAlert,那只是我对 UIViewController 的扩展。但是我在您的代码中没有看到的是 paymentQueueRestoreCompletedTransactionsFinished(_ queue:).

我遵循了相同的教程我认为你没有 select select none 在这里

configuration

要在您的模拟器中恢复,您应该 select none 当您 select none 它会尝试在应用程序购买配置中连接苹果开发者。试试看,让我知道。