Ваша функция getProduct
не делает ничего, кроме как напечатать пустой массив (products
), отфильтровать этот пустой массив и извлечь первый элемент (который не существует).
Я предлагаю использовать помощник вот так (я откуда-то скопировал, не помню где):
import Foundation
import StoreKit
class IAPHelper: NSObject, SKProductsRequestDelegate, SKPaymentTransactionObserver {
typealias RequestProductsCompletionHandler = (_ success:Bool, _ products:[SKProduct]?) -> ()
var completionHandler: RequestProductsCompletionHandler?
var productsRequest: SKProductsRequest?
var productIdentifiers: Set<String>
var purchasedProductIdentifiers: Set<String>?
// MARK: - Init
init(identifiers: Set<String>) {
// Store product identifiers
productIdentifiers = identifiers;
// Check for previously purchased products
purchasedProductIdentifiers = Set()
for productIdentifier in productIdentifiers {
let productPurchased = UserDefaults.standard.bool(forKey: productIdentifier)
if productPurchased {
purchasedProductIdentifiers?.insert(productIdentifier)
print("Previously purchased: \(productIdentifier)");
} else {
print("Not purchased: \(productIdentifier)");
}
}
super.init() // must be called after subclass init, but before "self" is used
SKPaymentQueue.default().add(self)
} // init
func requestProductsWithCompletionHandler(_ completionHandler: @escaping RequestProductsCompletionHandler) {
self.completionHandler = completionHandler
productsRequest = SKProductsRequest.init(productIdentifiers: productIdentifiers)
productsRequest!.delegate = self
productsRequest!.start()
}
// MARK: - Products request delegate
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
productsRequest = nil
let skProducts = response.products
for skProduct in skProducts {
print("Found product: \(skProduct.productIdentifier), \(skProduct.localizedTitle), \(skProduct.price.floatValue)");
}
completionHandler!(true, skProducts)
completionHandler = nil
}
func request(_ request: SKRequest, didFailWithError error: Error) {
// NOTE: If this happens on the simulator, close the simulator window and re-run the app. This helps normally !!!
print("Failed to load list of products. Error: \(error)")
productsRequest = nil
completionHandler!(false, nil)
completionHandler = nil
}
// MARK: - Purchase
func productPurchchased(_ productIdentifier:String) -> Bool {
return purchasedProductIdentifiers!.contains(productIdentifier)
}
func buyProduct(_ product:SKProduct) {
print("Buying \(product.productIdentifier)");
let payment = SKPayment(product: product)
SKPaymentQueue.default().add(payment)
}
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
switch transaction.transactionState {
case SKPaymentTransactionState.purchased:
self.completeTransaction(transaction)
case SKPaymentTransactionState.failed:
self.failedTransaction(transaction)
case SKPaymentTransactionState.restored:
self.restoreTransaction(transaction)
default:
print("Error: Unknown SKPaymentTransactionState")
}
}
}
func completeTransaction(_ transaction:SKPaymentTransaction) {
print("completeTransaction...");
self.provideContentForProductIdentifier(transaction.payment.productIdentifier)
SKPaymentQueue.default().finishTransaction(transaction)
}
func restoreTransaction(_ transaction:SKPaymentTransaction) {
print("restoreTransaction...");
self.provideContentForProductIdentifier(transaction.original!.payment.productIdentifier)
SKPaymentQueue.default().finishTransaction(transaction)
}
func failedTransaction(_ transaction:SKPaymentTransaction) {
print("failedTransaction...");
if let error = transaction.error as NSError?, error.code == SKError.paymentCancelled.rawValue {
print("Transaction error:\(error.localizedDescription)");
}
SKPaymentQueue.default().finishTransaction(transaction)
}
func provideContentForProductIdentifier(_ productIdentifier:String) {
purchasedProductIdentifiers?.insert(productIdentifier)
UserDefaults.standard.set(true, forKey:productIdentifier)
NotificationCenter.default.post(name: Notification.Name(rawValue: IAPHelperProductPurchasedNotification), object: productIdentifier, userInfo: nil)
}
func restoreCompletedTransactions() {
SKPaymentQueue.default().restoreCompletedTransactions()
}
}