Question

How to detect when subscription is expired when launching app (SwiftUI)?

  • 13 November 2023
  • 2 replies
  • 23 views

Badge

I’m playing with a sandbox account and trying to disable premium features when the entitlement is no longer present. I have tried using the following code:

Purchases.shared.getCustomerInfo { customerInfo, error in
self.isActive = customerInfo?.entitlements["premium"]?.isActive == true
}

Setting a @State-var named isActive. It does get set to true when I make a test purchase, but when I cancel the subscription I never get false. If I kill my app and relaunch it I get an updated value saying false. How do I detect that a subscription/entitlement has expired between app launches? It seems everything is cached until I kill the app and then launch it again. I want the status to be updated at least every time the app enters the foreground. Any best practice for this? 


2 replies

Userlevel 5
Badge +8

Hey @mjdragon!

This is going to depend on how often you’re calling `getCustomerInfo` - you’ll need to keep calling this method to get the latest CustomerInfo from RevenueCat’s API. In general, I would recommend calling this method every time you attempt to access premium features in the app.

It’s also worth mentioning that the SDK will cache the results for a short period of time, which is why it’s safe to call as often as you need. After ~5 minutes, the cache will be invalidated and a network call will be made instead.

If you specifically want to refresh on app foreground, you can use the `scenePhase` property in SwiftUI: https://www.hackingwithswift.com/books/ios-swiftui/how-to-be-notified-when-your-swiftui-app-moves-to-the-background

Badge

Hey @mjdragon!

If you specifically want to refresh on app foreground, you can use the `scenePhase` property in SwiftUI: https://www.hackingwithswift.com/books/ios-swiftui/how-to-be-notified-when-your-swiftui-app-moves-to-the-background

Thank you, I now have a check in scenePhase. It kind of works. If I cancel my subscription and then wait a really long time like 30 minutes after subscription is cancelled, then start my app - I still get that the subscription is active. However If I call getCustomerInfo one more time the status updates. I have now solved it by first calling getCustomerInfo on scenePhase-change, then wait 2 seconds and check getCustomerInfo one more time. I don’t know why getCustomerInfo needs to be called twice to get out of “cache mode”.

This is my code:

.onChange(of: scenePhase) { _ in
self.subscriptionStatus.refresh()

DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.subscriptionStatus.refresh()
}
}

All the refresh-method does is:

Purchases.shared.getCustomerInfo { customerInfo, error in
DispatchQueue.main.async {
self.isActive = customerInfo?.entitlements["premium"]?.isActive == true
}
}

Where isActive is a @Published property in a class with ObservableObject-protocol.

Reply