ユーザーがアイテムを購入しようとすると、アプリの Xcode クラッシュ レポートに次のエラーが表示されます。一部のユーザーはアイテムを購入でき、一部のユーザーは購入できないため、エラーは一般的なエラーではありません。
libobjs.A.dylib objc_msgSend
StoreKit __34-[SKProductsRequest_handleReply:]_block_invoke
libdispatch.dylib _dispatch_call_block_and_release
libdispatch.dylib _dispatch_client_callout
libdispatch.dylib _dispatch_main_queue_callback_4CF
私のコードは以下です。エラーがどこから来るのか本当に理解できません。誰でも何か考えがありますか?
ありがとう、ボグダン
@IBAction func unlockRemoveAds(_ sender: Any) {
purchaseMyProduct(product: iapProducts[3])
}
@IBAction func unlockExtraLessons(_ sender: Any) {
purchaseMyProduct(product: iapProducts[0])
}
@IBAction func unlockExtraTests(_ sender: Any) {
purchaseMyProduct(product: iapProducts[1])
}
@IBAction func unlockFullPackageDeal(_ sender: Any) {
purchaseMyProduct(product: iapProducts[2])
}
@IBAction func restorePurchaseButt(_ sender: Any) {
SKPaymentQueue.default().add(self)
SKPaymentQueue.default().restoreCompletedTransactions()
}
func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
nonConsumablePurchaseMade = true
UserDefaults.standard.set(nonConsumablePurchaseMade, forKey: "nonConsumablePurchaseMade")
UIAlertView(title: "Grammar PRO!",
message: "You've successfully restored your purchase!",
delegate: nil, cancelButtonTitle: "OK").show()
}
func fetchAvailableProducts() {
let productIdentifiers = NSSet(objects:
removeAds,
extraLessonsDeal,
extraTestsDeal,
fullPackageDeal
)
print(productIdentifiers)
productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers as! Set<String>)
productsRequest.delegate = self
productsRequest.start()
}
func productsRequest (_ request:SKProductsRequest, didReceive response:SKProductsResponse) {
if (response.products.count > 0) {
iapProducts = response.products
// Remove Ads Deal
let removeAdsDeal = response.products[3] as SKProduct
let numberFormatter = NumberFormatter()
numberFormatter.formatterBehavior = .behavior10_4
numberFormatter.numberStyle = .currency
numberFormatter.locale = removeAdsDeal.priceLocale
categ1Price.text = numberFormatter.string(from: removeAdsDeal.price)
// ExtraLessonDeal
let ExtraLessonDeal = response.products[0] as SKProduct
numberFormatter.locale = ExtraLessonDeal.priceLocale
categ2Price.text = numberFormatter.string(from: ExtraLessonDeal.price)
// ExtraTestDeal
let ExtraTestDeal = response.products[1] as SKProduct
numberFormatter.locale = ExtraTestDeal.priceLocale
categ3Price.text = numberFormatter.string(from: ExtraTestDeal.price)
// FullPackageDeal
let FullPackageDeal = response.products[2] as SKProduct
numberFormatter.locale = FullPackageDeal.priceLocale
categ4Price.text = numberFormatter.string(from: FullPackageDeal.price)
}
}
// MARK: - MAKE PURCHASE OF A PRODUCT
func canMakePurchases() -> Bool { return SKPaymentQueue.canMakePayments() }
func purchaseMyProduct(product: SKProduct) {
if self.canMakePurchases() {
let payment = SKPayment(product: product)
SKPaymentQueue.default().add(self)
SKPaymentQueue.default().add(payment)
print("PRODUCT TO PURCHASE: \(product.productIdentifier)")
productID = product.productIdentifier
print(productID)
// IAP Purchases dsabled on the Device
} else {
UIAlertView(title: "Sorry!",
message: "Purchases are disabled in your device!",
delegate: nil, cancelButtonTitle: "OK").show()
}
}
// MARK:- IAP PAYMENT QUEUE
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
//print("add paymnet")
//print(extraLessonsDeal)
for transaction:AnyObject in transactions {
if let trans = transaction as? SKPaymentTransaction {
// print(trans.error)
switch trans.transactionState {
case .purchased:
if productID == removeAds {
print("remove ads")
e_1_dbhelper.updateNoAds()
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
UIAlertView(title: "Thank you for your purchase :-)",
message: "You've successfully removed ads!",
delegate: nil,
cancelButtonTitle: "OK").show()
let secondViewController:UIViewController = a_1_meniu()
self.present(secondViewController, animated: false, completion: nil)
}
else if productID == "com.labsterzz.extraLessonsDeal" {
print("extra lessons")
e_1_dbhelper.updateNoAds()
e_1_dbhelper.updateExtraLessons()
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
UIAlertView(title: "Thank you for your purchase :-)",
message: "You've successfully unlocked Extra Lessons Deal!",
delegate: nil,
cancelButtonTitle: "OK").show()
let secondViewController:UIViewController = b_2_learning()
let navigationController = UINavigationController(rootViewController: secondViewController)
self.present(navigationController, animated: false, completion: nil)
}
else if productID == extraTestsDeal {
print("extra tests")
e_1_dbhelper.updateNoAds()
e_1_dbhelper.updateExtraTests()
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
UIAlertView(title: "Thank you for your purchase :-)",
message: "You've successfully unlocked Extra Tests Deal!",
delegate: nil,
cancelButtonTitle: "OK").show()
let secondViewController:UITableViewController = b_1_choose_test()
let navigationController = UINavigationController(rootViewController: secondViewController)
self.present(navigationController, animated: false, completion: nil)
}
else if productID == fullPackageDeal {
print("full package")
e_1_dbhelper.updateNoAds()
e_1_dbhelper.updateExtraLessons()
e_1_dbhelper.updateExtraTests()
e_1_dbhelper.updateFullPackage()
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
UIAlertView(title: "Thank you for your purchase :-)",
message: "You've successfully unlocked Full Package Deal!",
delegate: nil,
cancelButtonTitle: "OK").show()
let secondViewController:UIViewController = a_1_meniu()
self.present(secondViewController, animated: false, completion: nil)
}
// SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
// break;
case .failed:
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
break
case .restored:
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
break
case .deferred:
break
case .purchasing:
break
default:
print((transaction.transactionState.rawValue))
}}}
}