Skip to main content

Hello! I’m developing a SwiftUI app and am using code from the Magic Weather example app to implement a paywall for my subscription. The initial version is working just like I would expect it to (displaying the correct names, prices, duration, etc).  However, I started thinking about different scenarios to see if my code would handle them. One of the first things I tried is causing me concern.  If I launch the app with no connectivity I see errors logged, which is not unexpected. When I restore connectivity I almost immediately see some RC activity.

 

tPurchases] - DEBUG: ℹ️ applicationDidBecomeActive

pPurchases] - DEBUG: ℹ️ CustomerInfo cache is stale, updating from network in foreground.

/Purchases] - DEBUG: ℹ️ Offerings cache is stale, updating caches

 

However, when I view my paywall (which is just PaywallView.swift from the SwiftUI Magic Weather at this point) there are no offerings displayed. I added some logging and UserViewModel.shared.offerings is still nil even after connectivity is restored. 

I noticed this comment where UserViewModel.shared.offerings is declared.

    /* The latest offerings - fetched from MagicWeatherApp.swift on app launch */
    @Published var offerings: Offerings? = nil

Since I didn’t have connectivity on app launch I guess that makes sense why it’s still nil for me in my scenario. I changed my code to check if the app has come back into the foreground and see if UserViewModel.shared.offerings is nil. If so I have it do the same thing that is done upon app launch:

      UserViewModel.shared.offerings = try await Purchases.shared.offerings()

This seems to fix the problem.

My questions:

  1. Is the scenario I’m testing an oversight or is there logic in Magic Weather that would handle this that I didn’t copy over?
  2. If it is an oversight is the way I handled it what you would recommend?

Xcode says I’m using “RevenueCat 4.17.3”.

Thank you!

Hi Sharif.

That line you highlighted is only called once when the app first launches. If there’s no connectivity when it is executed then the UserViewModel stays empty because it appears that the sample app doesn’t have any code that tries to populate it again. Because I don’t fully understand how the UserViewModel works I was a little hesitant to populate it in another place. But from what you said it sounds like the approach I took is fine. Thanks for taking the time to comment.


Hey Chris!

Personally I’m not a SwiftUI expert so I don’t know the most elegant SwiftUI way to do this, but your thinking is in line with what I see. In the sample app the offerings are fetched when the app is launched here: https://github.com/RevenueCat/purchases-ios/blob/7985b03cb8ccc546e51dec8f18ac9eea76932e34/Examples/MagicWeatherSwiftUI/Shared/Sources/Lifecycle/MagicWeatherApp.swift#L45 

If you want, you can call UserViewModel.shared.offerings = try await Purchases.shared.offerings() whenever the paywall is shown. You can also have a refresh button if offerings can’t be refreshed (e.g. “Connection error. Tap to try again.”)


Reply