skip to Main Content

I recently transitioned to StoreKit 2 to handle the active subscription within my app. But there is some aspect of it I’m not entirely sure. The documentation about the revocationDate and expiration date are not clear to me.

  1. If a user cancel his auto-renewable while being in a 7 day trial, will the revocation date be non nil?

  2. Does Transaction.currentEntitlements only contains currently active product? I’m assuming I don’t really need to check if the expirationDate is expired or not if that’s the case.

  3. Is it recommended to execute this code in the MainThread?

Here is the full method :

    @MainActor
    func syncActiveAppleProduct() async {
        LoggerManager.shared.warning("[Fetch Current Entitlements]")
        
        var activeSubscriptions: [Product] = []

        for await result in Transaction.currentEntitlements {
            do {

                let transaction = try checkVerified(result)
                
                guard let subscription: Product = subscriptions.first(where: { $0.id == transaction.productID }) else {
                    continue
                }
                
                switch transaction.productType {
                case .autoRenewable:
                    guard transaction.revocationDate == nil else { continue }

                    if let expirationDate = transaction.expirationDate {
                        KeychainHelper.Subscription.setExpiryOrCancelledDate(expirationDate)
                    }
                    activeSubscriptions.append(subscription)
                    
                case .consumable, .nonConsumable, .nonRenewable:
                    guard let expirationDate = getNonRenewingExpirationDate(forProductId: transaction.productID, purchaseDate: transaction.purchaseDate) else { continue }
                    if Date() < expirationDate {
                        KeychainHelper.Subscription.setExpiryOrCancelledDate(expirationDate)
                        activeSubscriptions.append(subscription)
                    }
                default:
                    continue
                }
                
            } catch let error {
                LoggerManager.shared.error(error: error, message: "Failed update active customer product.")
            }
        }

        self.activeSubscriptions = activeSubscriptions
    }

2

Answers


  1. The revocationDate is the date when the App Store revoked the transaction. This can happen when the user gets a refund for the purchase or if the payment was found to be fraudulent. in trail the revocation does not get set, revocationDate remains nil.

    Transaction.currentEntitlements will provide you with all the entitlements for the user, like access to content. However, just of that right does not mean its active. You still need to check the expirationDate for auto-renewable subscriptions to see if they are active.

    you use the @MainActor attribute that ensures network calls not to freeze the Ui.

    Login or Signup to reply.
    1. if auto-renewable subscription is cancelled during trial period, revocationDate will be set when the trial period ends, because subscription was not technically active during this time.

    2. Yes, Transaction.currentEntitlements only includes currently active products. If the subscription is expired or cancelled, it will not be included in the returned list, but for non-renewing subscriptions, you may need to check the expiration date to determine if the user has access to the subscription benefits

    3. most of the storekit methods and callbacks are automatically executed on the main thread, so yes It is recommended to execute code in the main thread, this will also ensure there are not any potential threading issues

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search