Informing the user about the result of async Purchases.shared.restorePurchases()

  • 26 October 2022
  • 2 replies
  • 96 views

Userlevel 1
Badge +5

The sample app is pretty light when it comes to restoring purchases:          

            Button("Restore Purchases") {
Task {
try? await Purchases.shared.restorePurchases()
}
}

There are 3 possible outcomes when it comes to a subscription:

  • Success
  • Failure due to lack of active subscription
  • Error

I want to be able to show an alert of sorts in all 3 cases.

My view has two variables:

@Environment(\.isPremium) var isPremium
@EnvironmentObject var customer: Customer

Where customer is Purchases’ delegate and has the CustomerInfo

and isPremium derives its value from that customer, an @ObservedObject of my app:

.environment(\.isPremium, customer.isPremium)

The button to restore looks like this.

                Button(action: {
isRestoringPurchase = true
Task {
do {
let _ = try await Purchases.shared.restorePurchases()
} catch {
// Inform user of error
}
// Inform user of result based on customer.isPremium
isRestoringPurchase = false
}
})

This works fine: restorePurchases() calls its delegate (which is  and customer is updated by the time I use it to inform the user.

But, if I use the env var isPremium instead of customer.isPremium, its value is not updated in time to inform the user, but only shortly after.

Two questions:
1. why the lag? It feels like it’s just a matter of one cycle being missed.
2. is there another way to approach this?


2 replies

Userlevel 1
Badge +5

Hi Arnaud!

 

Can you try putting both of those properties into a single class conforming to ObservableObject? Josh Holtz has an example of this in his Super Basic SwiftUI app.

Customer is already the OO that holds both properties. I just have an extra Environment value to avoid calling the OO everywhere that value is needed, it feels superfluous.
But, in the specific context of this view that is both using it AND updating it after a successful restore, it’s problematic.
It’s more a SwiftUI question than a RCat one.

Hi Arnaud!

 

Can you try putting both of those properties into a single class conforming to ObservableObject? Josh Holtz has an example of this in his Super Basic SwiftUI app.

Reply