[英]InApp Purchases localized price fatal error
我将此代码用于我的应用内购买以显示本地化价格:
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.
我不明白错误在哪里。 在某些情况下,此代码有效,但在某些情况下会出现致命错误。
这个
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.