InApp购买本地化的价格致命错误

时间:2020-02-12 13:39:46

标签: ios swift in-app-purchase

我正在使用此代码进行inApp购买以显示本地化价格:

private func priceStringFor(product: SKProduct) -> String {
    let numberFormatter = NumberFormatter()
    numberFormatter.numberStyle = .currency
    numberFormatter.locale = product.priceLocale
    return numberFormatter.string(from: product.price)!
}


override func viewDidLoad() {
    super.viewDidLoad()
    perYearPrice.setTitle("\(priceStringFor(product: IAPManager.shared.products[1])) per year", for: .normal)
    oneTimePrice.setTitle("\(priceStringFor(product: IAPManager.shared.products[0])) one time", for: .normal)
}

这是我的IAPManager代码:

import Foundation
import StoreKit

class IAPManager: NSObject {

    static let shared = IAPManager()
    private override init() {}

    var products: [SKProduct] = []
    let paymentQueue = SKPaymentQueue.default()

    public func setupPurchases(callback: @escaping(Bool) -> ()) {
        if SKPaymentQueue.canMakePayments() {
            paymentQueue.add(self)
            callback(true)
            return
        }
        callback(false)
    }

    public func getProducts() {
        let identifiers: Set = ["inapp1", "inapp2"]
        let productRequest = SKProductsRequest(productIdentifiers: identifiers)
        productRequest.delegate = self
        productRequest.start()
    }

    public func purchase(productWith identifier: String) {
        guard let product = products.filter({ $0.productIdentifier == identifier }).first else { return }
        let payment = SKPayment(product: product)
        paymentQueue.add(payment)
    }

    public func restoreCompletedTransactions() {
        paymentQueue.restoreCompletedTransactions()
    }

}

extension IAPManager: SKPaymentTransactionObserver {

func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
    for transaction in transactions {
        switch transaction.transactionState {
        case .deferred: break
        case .purchasing: break
        case .failed: failed(transaction: transaction)
        case .purchased: completed(transaction: transaction)
        case .restored: restored(transaction: transaction)
        @unknown default: fatalError()
        }
    }
 }

    func purchased() {
        let adRemovalPurchased = UserDefaults.standard
        adRemovalPurchased.set(true, forKey: "adRemoved")
        adRemovalPurchased.synchronize()
    }

    private func failed(transaction: SKPaymentTransaction) {
        if let transactionError = transaction.error as NSError? {
            if transactionError.code != SKError.paymentCancelled.rawValue {
                print("Error: \(transaction.error!.localizedDescription)")
            }
        }
        paymentQueue.finishTransaction(transaction)
    }

    private func completed(transaction: SKPaymentTransaction) {
        paymentQueue.finishTransaction(transaction)
        purchased()
    }

    private func restored(transaction: SKPaymentTransaction) {
        paymentQueue.finishTransaction(transaction)
        purchased()
    }

}

extension IAPManager: SKProductsRequestDelegate {
    func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        self.products = response.products
        products.forEach { print($0.localizedTitle) }
    }
}

我也将此代码放在AppDelegate中:

IAPManager.shared.setupPurchases { success in
    if success {
        print("can make payments")
        IAPManager.shared.getProducts()
    }
}

但是当我尝试获取IAPManager.shared.products [1]的本地化价格时,我会得到

Fatal error: Index out of range. 

我不知道错误在哪里。在某些情况下,此代码有效,但在某些情况下,它会导致致命错误。

1 个答案:

答案 0 :(得分:1)

IAPManager.shared.getProducts()

是一个异步方法,只有调用

后,您才能访问产品数组
var callBack:(() -> ())? // 1
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
    self.products = response.products
    products.forEach { print($0.localizedTitle) }
    callBack?() // 2
}

然后做

IAPManager.shared.setupPurchases { success in
    if success {
        print("can make payments")
        IAPManager.shared.callBack = { 
          // now access the products 
        }
        IAPManager.shared.getProducts()
    }
}  

顺便说一句,您可以使用https://github.com/bizz84/SwiftyStoreKit