Reputation: 240
I've made an Apple TV app but my in-app purchase doesn't respond. I have no idea what I'm doing wrong. I also don't get any build errors.
I added the in-app purchase to iTunes Connect, added the entitlement to my app ID and added the StoreKit framework. I tested my app on an Apple TV but when I press the button to buy my in-app purchase, nothing happens. When I press the button to restore the in-app purchases it does ask to log in with my apple ID so I guess that works.
This is the class I use for in-app purchases:
import Foundation
import StoreKit
class InAppPurchase : NSObject, SKProductsRequestDelegate, SKPaymentTransactionObserver {
let kInAppProductPurchasedNotification = "InAppProductPurchasedNotification"
let kInAppPurchaseFailedNotification = "InAppPurchaseFailedNotification"
let kInAppProductRestoredNotification = "InAppProductRestoredNotification"
let kInAppPurchasingErrorNotification = "InAppPurchasingErrorNotification"
class var sharedInstance : InAppPurchase {
struct Static {
static var onceToken: dispatch_once_t = 0
static var instance: InAppPurchase? = nil
}
dispatch_once(&Static.onceToken) {
Static.instance = InAppPurchase()
}
return Static.instance!
}
override init() {
super.init()
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
}
func buyProduct(product: SKProduct) {
print("Sending the Payment Request to Apple")
let payment = SKPayment(product: product)
SKPaymentQueue.defaultQueue().addPayment(payment)
}
func restoreTransactions() {
SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
}
func request(request: SKRequest, didFailWithError error: NSError) {
print("Error %@ \(error)")
NSNotificationCenter.defaultCenter().postNotificationName(kInAppPurchasingErrorNotification, object: error.description)
}
func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) {
print("Got the request from Apple")
let count: Int = response.products.count
if count > 0 {
_ = response.products
let validProduct: SKProduct = response.products[0]
print(validProduct.localizedTitle)
print(validProduct.localizedDescription)
print(validProduct.price)
buyProduct(validProduct);
}
else {
print("No products")
}
}
func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
print("Received Payment Transaction Response from Apple");
for transaction: AnyObject in transactions {
if let trans: SKPaymentTransaction = transaction as? SKPaymentTransaction {
switch trans.transactionState {
case .Purchased:
print("Product Purchased")
savePurchasedProductIdentifier(trans.payment.productIdentifier)
SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction)
NSNotificationCenter.defaultCenter().postNotificationName(kInAppProductPurchasedNotification, object: nil)
break
case .Failed:
print("Purchased Failed")
SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction)
NSNotificationCenter.defaultCenter().postNotificationName(kInAppPurchaseFailedNotification, object: nil)
break
case .Restored:
print("Product Restored")
savePurchasedProductIdentifier(trans.payment.productIdentifier)
SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction)
NSNotificationCenter.defaultCenter().postNotificationName(kInAppProductRestoredNotification, object: nil)
break
default:
break
}
}
}
}
func savePurchasedProductIdentifier(productIdentifier: String!) {
NSUserDefaults.standardUserDefaults().setObject(productIdentifier, forKey: productIdentifier)
NSUserDefaults.standardUserDefaults().synchronize()
}
func unlockProduct(productIdentifier: String!) {
if SKPaymentQueue.canMakePayments() {
let productID: NSSet = NSSet(object: productIdentifier)
let productsRequest: SKProductsRequest = SKProductsRequest(productIdentifiers: productID as! Set)
productsRequest.delegate = self
productsRequest.start()
print("Fetching Products")
}
else {
print("Сan't make purchases")
NSNotificationCenter.defaultCenter().postNotificationName(kInAppPurchasingErrorNotification, object: NSLocalizedString("CANT_MAKE_PURCHASES", comment: "Can't make purchases"))
}
}
func buyUnlockSeasonsPack() {
unlockProduct("Company.SeasonsPack")
}
}
And these are my IBAction functions for my buttons:
@IBAction func getSeasonsPack(sender: UIButton) { InAppPurchase.sharedInstance.buyUnlockSeasonsPack() } @IBAction func RestorePurchases(sender: UIButton) { InAppPurchase.sharedInstance.restoreTransactions() }
Please help me.
Upvotes: 2
Views: 509
Reputation: 686
You need retain your productsRequest because it got released automatically at the end of func unlockProduct() and the following callbacks won't be fired.
Simply declare it as a class level variable.
Upvotes: 2