Austin M
Austin M

Reputation: 11

SKProduct returns nil the first time, works later

My issue is weird -- I've never seen it in a forum before. Upon requesting an IAP (getPurchaseInfo() —> request.start()) the first time I click on it, it gives me an error with no products found. However, if I try again immediately it accepts the product ID and allows the purchase. Apple rejected my submission since I have this error at first and I can't figure out how to make it go away.

There are many functions I have to work with the IAP, these are some of the ones I think might be helpful.

func getPurchaseInfo() {
        if SKPaymentQueue.canMakePayments() {
            let request = SKProductsRequest(productIdentifiers: NSSet(objects: self.productID) as! Set<String>)
            request.delegate = self
            request.start()
            print("Completed Product Request.")
        }

func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        var products = response.products
        print(products.count)
        if products.count == 0 {
            //Tell the user there are no products found!
            let prodError = UIAlertController(title: "Error", message: "No products were found.", preferredStyle: .alert)
            let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
            prodError.addAction(okAction)
            self.view?.window?.rootViewController?.present(prodError, animated: true, completion: nil)
        }
        else {
            product = products[0]
            print(productID)
        }

I get "Completed Product Request" printed, and even get a products.count of 1, as well as the correct productID, meaning there is a product. However, I still get an error message (with an AlertController that I set up for this case) telling me there is no product, and if I remove the AlertController I made to show me that error the app crashes, implying the product cannot be found. Here is the function where I click a button to buy the IAP:

func purchase() {
        SKPaymentQueue.default().add(self)
        self.getPurchaseInfo()
        if self.product == nil {
            let errorPurchasing = UIAlertController(title: "Error", message: "There was an error requesting the purchase. Please try again.", preferredStyle: .alert)
            let okayButton = UIAlertAction(title: "OK", style: .default, handler: nil)
            errorPurchasing.addAction(okayButton)     
            self.view?.window?.rootViewController?.present(errorPurchasing, animated: true, completion: nil)
        }
        else {
            let payment = SKPayment(product: self.product!)
            SKPaymentQueue.default().add(payment)
            if let myP = self.product {
                let payment = SKPayment(product: myP)
                SKPaymentQueue.default().add(payment)
            }
        }
}

I always get the "Error Purchasing" alert I have set up when I click it for the first time, but not after that while the app is open. It just doesn't make sense that it wouldn't find it the first time but it would the second time.

Upvotes: 1

Views: 682

Answers (1)

rounak
rounak

Reputation: 9397

I would suggest holding on to the SKProductsRequest in an instance variable so that it doesn't get deallocated.

so something like

self.request = SKProductsRequest(....)

Upvotes: 2

Related Questions