In-App Purchase Restore - No observers found

When I execute a restore on my in-app purchase I'm getting a warning, however the restore is successfully executed. I think this is something new with Xcode 14.3. My test device is running iOS 16.4

This is the warning: <SKPaymentQueue: 0x283708a80>: No observers found that respond to "paymentQueue:shouldAddStorePayment:forProduct:", will not check for purchase intents

It fires at this point in the code. If I comment out the first line, I don't get the warning however, the restore doesn't execute. Is anybody else seeing this or do I have something wrong in my code? I know it's only a warning but any help would be appreciated.

@IBAction func restoreButtonTapped(_ sender: UIBarButtonItem)
{
        SKPaymentQueue.default().add(self)
        SKPaymentQueue.default().restoreCompletedTransactions()
}

I've included the rest of the code just for a completeness.

func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction])
    {
        for transaction in transactions
        {
            switch transaction.transactionState
            {
            case .purchasing:
                &#x2F;&#x2F;print("Purchase in progress...")
                break
                
            case .purchased:
                &#x2F;&#x2F;print("Purchase Successful")
                
                SKPaymentQueue.default().finishTransaction(transaction)
                &#x2F;&#x2F;print("Transaction Complete")
                
		&#x2F;&#x2F; Hide the restore button
                navigationItem.setRightBarButton(nil, animated: true)
                
                &#x2F;&#x2F;Set the BaseVerion in the Db to true
                IAPHandler.set_BaseVersion_To_Purchased()
                
                &#x2F;&#x2F;Also hide the Purchase button
                UIView.animate(withDuration: 1.0, animations: { [weak self] in
                    self?.purchaseButton.alpha = 0
                }) { [weak self] (success) in
                    self?.selector_Top_Constraint.constant = 30
                }
                
            case .failed:
                if let error = transaction.error
                {
                    let errorDescription = error.localizedDescription
                    print("Transaction failed due to error: \(errorDescription)")
                }
                
            case .restored:
                
                SKPaymentQueue.default().finishTransaction(transaction)
                &#x2F;&#x2F;print("Transaction Complete")
                
		&#x2F;&#x2F; Hide the restore button
                navigationItem.setRightBarButton(nil, animated: true)
                
                &#x2F;&#x2F; Set the BaseVerion in the Db to true
                IAPHandler.set_BaseVersion_To_Purchased()
                
                &#x2F;&#x2F; Also hide the Purchase button
                UIView.animate(withDuration: 1.0, animations: { [weak self] in
                    self?.purchaseButton.alpha = 0
                }) { [weak self] (success) in
                    self?.selector_Top_Constraint.constant = 30
                }
                
            case .deferred:
                &#x2F;&#x2F;print("Purchase Deferred")
                break
                
            @unknown default:
                if let error = transaction.error
                {
                    let errorDescription = error.localizedDescription
                    print("Transaction failed due to error: \(errorDescription)")
                }
                break
            }
        }
    }




    @IBAction func purchaseButtonTapped(_ sender: UIButton)
    {
        let theAlert = UIAlertController.init(title: K.Titles.pleaseChoose, message: nil, preferredStyle: .actionSheet)
        let theCancleAction = UIAlertAction(title: K.Titles.cancel, style: .cancel)
        
        let thePurchaseAction = UIAlertAction(title: K.DefaultList_Buttons.purchase_BaseVersion_Btn, style: .default) { [weak self] (action2) in
            
            if SKPaymentQueue.canMakePayments()
            {
                &#x2F;&#x2F; User can make payments
                let paymentRequest = SKMutablePayment()
                
                paymentRequest.productIdentifier = self!.base_Product_ID
                
                SKPaymentQueue.default().add(self!)
                
                SKPaymentQueue.default().add(paymentRequest)
                
            } else {
                &#x2F;&#x2F; User cannot make payments
                print("User cannot make payments")
            }
        }
        
        theAlert.addAction(thePurchaseAction)
        theAlert.addAction(theCancleAction)
        
        theAlert.setValue(NSAttributedString(string: theAlert.title ?? "", attributes: [.font : UIFont.systemFont(ofSize: (gDefaultTextSize - 2), weight: UIFont.Weight.semibold)]), forKey: "attributedTitle")
        
        let popOver = theAlert.popoverPresentationController
        popOver?.sourceView = sender
        popOver?.sourceRect = sender.bounds
        popOver?.permittedArrowDirections = .any
        present(theAlert, animated: true)
    }

Accepted Reply

func paymentQueue(_ queue: SKPaymentQueue,
                  shouldAddStorePayment payment: SKPayment,
                  for product: SKProduct) -> Bool {
    true
}

Replies

To eliminate warning add:

- (BOOL)paymentQueue:(SKPaymentQueue *)queue
shouldAddStorePayment:(SKPayment *)payment
          forProduct:(SKProduct *)product{
    return true;
}
  • Thanks for the rely. Where should I add this code?

Add a Comment

Just above your existing paymentQueue code would work.

  • Cannot find 'BOOL' in scope

    Cannot find 'shouldAddStorePayment' in scope

  • Sorry, my code is C. Adjust for Swift.

Add a Comment

Here's the Swift version:

func paymentQueue(_ queue: SKPaymentQueue, shouldAddStorePayment payment: SKPayment, for product: SKProduct) -> Bool {
        return true
}
func paymentQueue(_ queue: SKPaymentQueue,
                  shouldAddStorePayment payment: SKPayment,
                  for product: SKProduct) -> Bool {
    true
}

I started to receive this warning because Firebase was getting initialized before my SKPaymentQueue delegate