Reputation: 434
I've implemented an in app purchase into my app. It works intermittently.
Around 1/3 times it will crash, here is how I implemented it in an SKScene:
class GameOverMenu: SKScene, UIAlertViewDelegate, GKGameCenterControllerDelegate, SKProductsRequestDelegate, SKPaymentTransactionObserver {
var activeProduct: SKProduct?
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
switch (transaction.transactionState) {
case .purchased:
SKPaymentQueue.default().finishTransaction(transaction)
print("Purchased")
case .failed:
SKPaymentQueue.default().finishTransaction(transaction)
print("Failed")
default:
break
}
}
}
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
print("loaded products")
for product in response.products {
print("Product: \(product.productIdentifier), \(product.localizedTitle), \(product.price.floatValue)")
activeProduct = product
}
}
override func didMove(to view: SKView) {
SKPaymentQueue.default().add(self)
let productIdentifiers: Set<String> = ["gold_space_coins"]
let productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers)
productsRequest.delegate = self
productsRequest.start()
}
if(atPoint(location) == buyCoins){
if let activeProduct = activeProduct {
print("Buying \(activeProduct.productIdentifier)")
let payment = SKPayment(product: activeProduct)
SKPaymentQueue.default().add(payment)
}else{
print("No product")
}
}
Here is the log when the crash happens:
loaded products
Product: gold_space_coins, 500 Pieces of Gold Coins, 0.99
Here I exited the scene then returned**
loaded products
Product: gold_space_coins, 500 Pieces of Gold Coins, 0.99
Buying gold_space_coins
warning: could not load any Objective-C class information. This will significantly reduce the quality of type information available.
It fails on line:
SKPaymentQueue.default().add(payment)
Should I have implemented this in the view controller instead perhaps? Or have I done something else wrong?
Upvotes: 2
Views: 227
Reputation: 934
This worked for me:
Swift 3
override func willMove(toParentViewController parent: UIViewController?) {
SKPaymentQueue.default().remove(self)
}
Upvotes: 0
Reputation: 434
SOLVED:
Upon leaving the scene I didn't remove the paymentQueue causing the memory problem when the scene came back into view.
This solved it:
override func willMove(from view: SKView) {
SKPaymentQueue.default().remove(self)
}
Upvotes: 1