Search code examples
iosswiftin-app-purchasein-app

iOS In-app purchase - unable to unlock the content as the function is in another view controller


I have set up an In-App purchase using a 'IAPHelper' class. I can retrieve the correct information from the App Store and display it in one VC. Once a user selects the required purchase item in that VC, the details are displayed on the next View Controller called 'Review'. This is where the actual purchase takes place. I have a 'buyProduct' function that is working fine in this ReviewVC, and sends the product payment to the paymentQueue of the SKPaymentTransactionObserver of the IAPHelper class. I need to unlock the content via a Pop Up in the 'Review VC' which should appear once the purchase status is shown as 'purchased' in the SKPaymentTransactionObserver, so I have tried many ways to include this function as part of the paymentQueue status for 'purchased' but the app always crashes after successful payment, once it reaches the function to show the PopUp. Here's some code - I won't include all the IAPHelper code, just the relevant pieces:

open class IAPHelper: NSObject { ......
var review: ReviewVC! ...... }

extension IAPHelper: SKPaymentTransactionObserver {

    public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for trans in transactions {
            print("func IAPHelper = \(trans.transactionState.status(), trans.payment.productIdentifier)")
            switch trans.transactionState {
            case .purchasing: break
            case .purchased: complete(transaction: trans)
                break
            case .failed : fail(transaction: trans)
            case .restored : restore(transaction: trans)
            case .deferred : break
           // default: queue.finishTransaction(trans)
            }
        }
    }

    func complete(transaction: SKPaymentTransaction) {
        deliverPurchaseNotificationFor(identifier: transaction.payment.productIdentifier)
        SKPaymentQueue.default().finishTransaction(transaction)
        review.showSuccessPopUp() //***ERROR IS HERE***Thread 1: EXC_BREAKPOINT (code=1, subcode=0x10426ac70)*****

    }

This is the code in the ReviewVC file:-

class ReviewVC: UIViewController {
 @IBAction func buyTestButton(_ sender: Any) {
        print("Buy button pressed - products = \(products?.localizedTitle ?? "No Product")")
        buyProduct()
    }

    func buyProduct() {
        let payment = SKPayment(product: products!)
        SKPaymentQueue.default().add(payment as SKPayment)

    }


    //SUCCESSFUL PURCHASE:-
    func showSuccessPopUp() {
        UIView.animate(withDuration: 0.4) {
            self.hideView.isHidden = false
        }
        UIView.animate(withDuration: 0.8) {
            self.successPopUp.isHidden = false
        }
    }

Been stuck on this for days so any help would be much appreciated!!


Solution

  • The problem is that review is nil.

    You are declaring it as a variable var review: ReviewVC! however, you are never initializing it.

    Initialization is something like review = Something.

    Not sure where your code is calling IAP() but wherever it is, I would do something like:

    var iap = IAP()
    iap.review = self //if you are in the review class. 
    

    Hard to tell as I am not sure where you declare your IAP object.