I have this code to handle in app purchase's
import Foundation
import StoreKit
class iap: NSObject, SKProductsRequestDelegate,SKPaymentTransactionObserver {
var productsArray = Array<SKProduct>()
var product: SKProduct?
override init()
{
super.init()
if SKPaymentQueue.canMakePayments() {
print("starting IAPS")
let productIdentifiers = Set(["com.blabla.bla.pro"])
let request = SKProductsRequest(productIdentifiers: productIdentifiers as Set<String>)
request.delegate = self
request.start()
} else {
print("please enable IAPS")
}
}
// 1
var list = [SKProduct]()
var p = SKProduct()
// 2
func buyProduct() {
print("buy " + p.productIdentifier)
let pay = SKPayment(product: p)
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
SKPaymentQueue.defaultQueue().addPayment(pay as SKPayment)
}
//3
func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) {
print("product request")
let myProduct = response.products
for product in myProduct {
print("product added")
print(product.productIdentifier)
print(product.localizedTitle)
print(product.localizedDescription)
print(product.price)
list.append(product )
}
}
// 4
func paymentQueueRestoreCompletedTransactionsFinished(queue: SKPaymentQueue) {
print("transactions restored")
for transaction in queue.transactions {
let t: SKPaymentTransaction = transaction
let prodID = t.payment.productIdentifier as String
switch prodID {
case "com.blabla.bla.pro":
print("pro upgrade update only basic stuff futher updates must be payed")
default:
print("IAP not setup")
}
}
}
// 5
func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
print("add paymnet")
for transaction:AnyObject in transactions {
let trans = transaction as! SKPaymentTransaction
print(trans.error)
switch trans.transactionState {
case .Purchased:
print("buy, ok unlock iap here")
print(p.productIdentifier)
let prodID = p.productIdentifier as String
switch prodID {
case "com.blabla.bla.pro":
print("pro upgrade update only basic stuff futher updates must be payed")
default:
print("IAP not setup")
}
queue.finishTransaction(trans)
break;
case .Failed:
print("buy error")
queue.finishTransaction(trans)
break;
default:
print("default")
break;
}
}
}
// 6
func finishTransaction(trans:SKPaymentTransaction)
{
print("finish trans")
SKPaymentQueue.defaultQueue().finishTransaction(trans)
}
//7
func paymentQueue(queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction])
{
print("remove trans");
}
}
And when a view is loaded I call the iap class:
class test: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
let inAppPurchase = iap()
}
}
The call works, but the only thing I see is starting iaps, than it crashes with this error: message sent to deallocated instance.
And this is the result when I log with zombies.
I have tried everything, but with this error as result. How can I solve this?
Your iap class is getting released when you go out of scope, after you make the request. Store it in a property to keep it alive:
class test: UITabBarController {
let inAppPurchase = iap()
override func viewDidLoad() {
super.viewDidLoad()
}
}