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.
-
If a user cancel his auto-renewable while being in a 7 day trial, will the revocation date be non nil?
-
Does
Transaction.currentEntitlements
only contains currently active product? I’m assuming I don’t really need to check if theexpirationDate
is expired or not if that’s the case. -
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
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.
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.
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
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