在 App Purchase - 检测用户是否已经进行了购买

In App Purchase - detect whether user has already made that purchase

我有以下代码可以进行应用内购买。一切正常,用户可以点击按钮购买(非消费品)。

目前我在 AppDelegate 中调用 getProducts()restorePurchases() - 当用户已经购买时,我假设它将通过 restorePurchases() - 获取如何检测是否已购买具有其 ID 的特定产品 至 f.e。隐藏那个按钮。

import Foundation
import StoreKit

class IAPService: NSObject {

    private override init() {}
    static let shared = IAPService() 
    var products = [SKProduct]()
    let paymentQueue = SKPaymentQueue.default() 
    private var purchasedProductIdentifiers: Set<String> = []

    func getProducts() {
        let product: Set = ["123456"]
        let request = SKProductsRequest(productIdentifiers: product)
        request.delegate = self
        request.start()
        paymentQueue.add(self)
    }

    func purchase() {
        guard let productToPurchase = products.first else { return }
        print(productToPurchase)
        let payment = SKPayment(product: productToPurchase)
        paymentQueue.add(payment)
    }

    func restorePurchases() {
        paymentQueue.restoreCompletedTransactions()
    }

}

extension IAPService: SKProductsRequestDelegate {

    func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        self.products = response.products
        for product in response.products {
            print(product.localizedTitle)
        }
    }

}

extension IAPService: SKPaymentTransactionObserver {

    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for transaction in transactions {
            print(transaction.transactionState.status(), transaction.payment.productIdentifier)
            switch transaction.transactionState {
            case .purchasing: break
            default: queue.finishTransaction(transaction)
            }
        }
    }

}

extension SKPaymentTransactionState {
    func status() -> String {
        switch self {
        case .deferred: return "deferred"
        case .failed: return "failed"
        case .purchased: return "purchased"
        case .purchasing: return "purchasing"
        case .restored: return "restored"
        }
    }
}

您需要检查 updatedTransactions 的回调以获得所需的 productIdentifier 及其状态 purchased/restored

func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
    for transaction in transactions {
        if transaction.payment.productIdentifier == "someId" && ( transaction.transactionState == .purchased || transaction.transactionState == .restored ) {
            // purchased / resorted
        } 
    }
}

有用的链接

https://www.raywenderlich.com/5456-in-app-purchase-tutorial-getting-started

in-app purchase in Swift with a single product