Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift: Promoted products (with RevenueCat) - Caching the defermentBlock

At the moment I'm trying to include promoted products in my app with the help of RevenueCat. Unfortunately it does not work. (I am using SwiftUI 1.0, so still with AppDelegate.)

What I have done so far:

I have implemented the following function in AppDelegate as said here (https://docs.revenuecat.com/discuss/5cff570754c3420045b379f3):

  func purchases(_ purchases: Purchases, shouldPurchasePromoProduct product: SKProduct, defermentBlock makeDeferredPurchase: @escaping RCDeferredPromotionalPurchaseBlock){
    let defermentBlock = makeDeferredPurchase
    
  }

Problem:

I think the problem is that I am running the defermentBlock in the wrong place. As it says here (https://sdk.revenuecat.com/ios/Protocols/RCPurchasesDelegate.html#/c:objc(pl)RCPurchasesDelegate(im)purchases:shouldPurchasePromoProduct:defermentBlock:), it should be called when the app is in the right state.

Currently I call the defermentBlock directly in the function like this:

func purchases(_ purchases: Purchases, shouldPurchasePromoProduct product: SKProduct, defermentBlock makeDeferredPurchase: @escaping RCDeferredPromotionalPurchaseBlock){
    let defermentBlock = makeDeferredPurchase
    
    // Should buy the product 
    defermentBlock { (transaction, info, error, cancelled) in
        if let purchaserInfo = info {
            Purchases.shared.purchaseProduct(product) { (transaction, purchaserInfo, error, userCancelled) in //this function works for products which are directly bought in the app
                if error == nil && !userCancelled{
                    try? CoreDataManagerNew.shared.updateUserInformation()
                }
            }
        }
    }
    
}

Now I have the following questions:

  • How do I cache the defermentBlock?
  • When is the app in the right state? It opens automatically when I press the buy button in the AppStore.

Another problem is that I cannot test the functionality. The suggested way from Apple (https://developer.apple.com/documentation/storekit/in-app_purchase/testing_promoted_in-app_purchases) somehow does not work.

Many thanks in advance!

like image 539
Lukas Avatar asked Jun 05 '21 16:06

Lukas


1 Answers

Make sure you are setting Purchases.shared.delegate = self after calling configure and not before (someone had that issue here).

Then implement the delegate function like:

    defermentBlock { (transaction, info, error, cancelled) in
        if let purchaserInfo = info {
            if error == nil && !userCancelled{
                try? CoreDataManagerNew.shared.updateUserInformation()
            }
        }
    }   

Note that you don't have to call purchaseProduct inside the block. Calling the block will be equivalent to calling purchaseProduct and it will open the purchase dialog.

With caching the defermentBlock we mean that you can save the deferment block as a property of your object and then call it whenever your app is ready to make the purchase. So you could do something like:

    var maybeDeferredPurchase: RCDeferredPromotionalPurchaseBlock? = nil
    
    func purchases(_ purchases: Purchases, shouldPurchasePromoProduct product: SKProduct, defermentBlock makeDeferredPurchase: @escaping RCDeferredPromotionalPurchaseBlock) {
        maybeDeferredPurchase = makeDeferredPurchase
    }

And then, whenever you want to show the purchase pop-up (like when the screen has loaded for example) do:

if let defermentBlock = self.maybeDeferredPurchase {
    defermentBlock { (transaction, info, error, cancelled) in
        if let purchaserInfo = info {
            handlePurchaserInfo()
        }
    }
}

To test it works, you can open a link like itms-services://?action=purchaseIntent&bundleId=<YOUR_BUNDLE_ID>&productIdentifier=<YOUR_SKPRODUCT_ID> in your device. For example, in my tester app it was itms-services://?action=purchaseIntent&bundleId=com.revenuecat.sampleapp&productIdentifier=com.revenuecat.lifetime.199.99.

like image 68
Cesar Avatar answered Nov 10 '22 03:11

Cesar