Skip to main content

New iOS and RevenueCat developer here, and I’m converting a paid app to subscription. I’ve read this article, and gone through the PurchasesHelper code.

 

To help me understand better, and so it’s easier for me to maintain later on, I prefer not to simply copy and paste code. So I’ve done my best to write this my self.

 

Since it’s difficult to test properly in a sandbox environment (or is beyond my technical know-how) and the importance of getting this right on the first try, I was wondering if someone can take a look at my code below and let me know if this will work in production:

 

In my app struct, I have:

 

@main
struct MyApp: App {

init() {
Purchases.logLevel = .error
Purchases.configure(
with: Configuration.Builder(withAPIKey: AppConstants.apiKey)
.with(storeKitVersion: .storeKit2)
.build()
)

Purchases.shared.delegate = PurchasesDelegateHandler.shared
}


var body: some Scene {
WindowGroup {
ContentView()
.task {
do {
// Fetch the available offerings
UserViewModel.shared.offerings = try await Purchases.shared.offerings()
} catch {
print("Error fetching offerings: \(error)")
}
}
}
}
}

 

and the UserViewModel:

 

/* Static shared model for UserView */
class UserViewModel: ObservableObject {

static let shared = UserViewModel()

/* The latest CustomerInfo from RevenueCat. Updated by PurchasesDelegate whenever the Purchases SDK updates the cache */
@Published var customerInfo: CustomerInfo? {
didSet {

// Purchased before build 6? Automatic entitlement to full app

if let originalApplicationVersion = customerInfo?.originalApplicationVersion {
if AppConstants.backwardsCompatibilityVersions.contains(originalApplicationVersion) {
subscriptionActive = true
return
}
}

// Otherwise, get current entitlement

subscriptionActive = customerInfo?.entitlementsfAppConstants.entitlementID]?.isActive == true

print(customerInfo?.originalApplicationVersion)
}
}

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

/* Set from the didSet method of customerInfo above, based on the entitlement set in Constants.swift */
@Published var subscriptionActive: Bool = false {
didSet {
subscriptionNotActive = !subscriptionActive
}
}

@Published var subscriptionNotActive: Bool = true
}

 

Is this sufficient? There will be a “Restore Purchases” button at the bottom of the PaywallView. If I’ve understood the PurchasesHelper GitHub documentation, a call to Purchases.shared.restorePurchases() is enough, and there is no need to call syncPurchases().

 

Is my understanding of restorePurchases() vs syncPurchases() correct?

 

Thank you!

Hey There,

 

Your understanding on calling restorePurchases() is correct. If the user wants to manually trigger a restore, that is the best way to do it. If you want to do this programmatically you will want to call syncPurchases(). 

 

As for the code, it looks pretty correct but we do not offer a direct code review. I would recommend running the app with debug logs and checking to see if everything is working correctly from there!