I am having a problem trying to purchase an IAP as a sandbox user. It's not the sandbox account that's the problem. It's the fact that my var products = [SKProduct]()
array in IAPService.swift is empty.
Inside my StoreViewController.swift (which also stores my Game Center leaderboards):
class StoreViewController: UIViewController, GKGameCenterControllerDelegate {
@IBAction func purchase(_ sender: UIButton) {
IAPService.shared.purchase(product: .nonConsumable)
}
...
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
IAPService.shared.getProducts()
print(IAPService.shared.products) // This is an empty array?
authenticateLocalPlayer() // Related to Game Center
}
}
Inside my IAPProducts.swift
enum IAPProducts: String {
case nonConsumable = "com.nameofgame.nameofproduct"
}
Inside my IAPService.swift
import Foundation
import StoreKit
class IAPService: NSObject {
private override init() {}
static let shared = IAPService()
var products = [SKProduct]()
let paymentQueue = SKPaymentQueue.default()
func getProducts() {
let products: Set = [IAPProducts.nonConsumable.rawValue,
]
let request = SKProductsRequest(productIdentifiers: products)
request.delegate = self
request.start()
paymentQueue.add(self)
}
func purchase(product: IAPProducts) {
guard let productToPurchase = products.filter({ $0.productIdentifier == product.rawValue }).first else { return }
let payment = SKPayment(product: productToPurchase)
paymentQueue.add(payment)
}
}
extension IAPService: SKProductsRequestDelegate {
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
products = response.products
}
}
extension IAPService: SKPaymentTransactionObserver {
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
switch transaction.transactionState {
case .purchased:
if transaction.payment.productIdentifier == IAPProducts.nonConsumable.rawValue {
print("IAP Purchased")
}
break
case .failed:
SKPaymentQueue.default().finishTransaction(transaction)
print(transaction.error!)
break
default: break
}
}
}
}
Things I've done several things to try and solve the problem:
Changed the
Set
in IAPService to an NSSet. This doesn't work because the set of Strings inlet request = SKProductsRequest(productIdentifiers: products)
cannot be converted to an NSSet.Checked multiple times that my BundleIDs match on Xcode and iTunes Connect. I've also done this check with the Product IDs to make sure there's a match between the IAP ID in iTunes Connect and the IAPProducts enum.
I added this IAP on iTunes Connect 3 days ago, and I've checked that all my contracts for paid apps are in effect.
Please help me with this issue. Thanks.