Auto-Renewable Subscriptions
What Are Auto-Renewable Subscriptions?
Auto-renewable subscriptions automatically renew at regular intervals (weekly, monthly, annually) until the user cancels. They are the most common subscription type for iOS apps.
Subscription Configuration
- Go to App Store Connect > Your App > In-App Purchases
- Click the plus button and select Auto-Renewable Subscription
- Choose a subscription group
- Set the product ID, pricing, and duration
Subscription Groups
Subscription groups organize related subscriptions. Users can only have one active subscription per group:
| Group Example | Products |
|---|---|
| Premium Tier | Monthly ($9.99), Annual ($79.99) |
| Content Tier | Basic ($4.99), Pro ($14.99) |
StoreKit 2 Subscription Implementation
import StoreKit
@Observable
class SubscriptionManager {
var currentSubscription: Product?
var subscriptionStatus: SubscriptionStatus = .unknown
enum SubscriptionStatus {
case unknown, active, expired, inGracePeriod
}
func checkSubscriptionStatus() async {
guard let product = currentSubscription else { return }
do {
let status = try await product.subscription?.status
if let status = status {
switch status.state {
case .subscribed:
subscriptionStatus = .active
case .expired:
subscriptionStatus = .expired
case .inGracePeriod:
subscriptionStatus = .inGracePeriod
default:
subscriptionStatus = .unknown
}
}
} catch {
print("Failed to check status: \(error)")
}
}
}
Entitlement Checking
func isEntitledTo(_ feature: String) async -> Bool {
for await result in Transaction.currentEntitlements {
if case .verified(let transaction) = result {
if transaction.productID == feature {
return true
}
}
}
return false
}
RevenueCat Integration
Why RevenueCat?
RevenueCat simplifies subscription management across iOS, Android, and web. It handles receipt validation, analytics, and A/B testing out of the box.
Setting Up RevenueCat
import RevenueCat
class RevenueCatManager {
static func configure() {
Purchases.logLevel = .debug
Purchases.configure(
with: Configuration.Builder(
withAPIKey: "your_revenuecat_api_key"
).build()
)
}
}
Offering Packages
func fetchOfferings() async {
do {
let offerings = try await Purchases.shared.offerings()
if let current = offerings.current {
let packages = current.availablePackages
for package in packages {
print("\(package.identifier): \(package.localizedPriceString)")
}
}
} catch {
print("Failed to fetch offerings: \(error)")
}
}
Purchasing with RevenueCat
func purchase(_ package: Package) async throws -> CustomerInfo {
let result = try await Purchases.shared.purchase(package: package)
return result.customerInfo
}
Checking Entitlements
func checkEntitlements() async -> Bool {
do {
let customerInfo = try await Purchases.shared.customerInfo()
return customerInfo.entitlements["premium"]?.isActive == true
} catch {
return false
}
}
Benefits of RevenueCat
- Cross-platform subscription management
- Built-in receipt validation
- Analytics and conversion tracking
- A/B testing for paywalls
- Customer support tools
Subscription Retention Strategies
Onboarding Optimization
First impressions determine retention. Guide users to the value proposition quickly:
struct PaywallView: View {
var body: some View {
VStack(spacing: 20) {
Text("Unlock Premium Features")
.font(.title)
FeatureList()
SubscriptionOptions()
Text("Cancel anytime")
.font(.caption)
.foregroundColor(.secondary)
}
}
}
Engagement Tracking
Monitor user engagement to predict churn:
struct EngagementTracker {
func trackSession() {
let defaults = UserDefaults.standard
let lastVisit = defaults.object(forKey: "lastVisit") as? Date
let sessionCount = defaults.integer(forKey: "sessionCount")
defaults.set(Date(), forKey: "lastVisit")
defaults.set(sessionCount + 1, forKey: "sessionCount")
if let lastVisit = lastVisit {
let daysSinceLastVisit = Calendar.current.dateComponents([.day], from: lastVisit, to: Date()).day ?? 0
if daysSinceLastVisit > 7 {
triggerReengagementNotification()
}
}
}
}
Churn Prevention
- Send personalized re-engagement emails
- Offer pause options before cancellation
- Provide feedback surveys for cancellations
- Create win-back campaigns for expired subscribers
Trial Optimization
- Keep trial length between 3-7 days
- Show value before trial ends
- Send reminders at 2 days and 1 day before expiration
- Make cancellation easy to build trust
Pricing Strategies
- Offer annual plans with significant discounts
- Consider regional pricing
- Test different price points with A/B testing
- Bundle subscriptions with other products
Quiz
1. What is a subscription group?
2. What is a benefit of using RevenueCat over direct StoreKit implementation?
3. What is the ideal trial length for most subscription apps?
4. What does Transaction.currentEntitlements return?
Flashcards
Question
What is an auto-renewable subscription?
Click to reveal answer
Answer
A subscription that automatically renews at regular intervals (weekly, monthly, annually) until the user cancels.
Question
What does RevenueCat simplify?
Click to reveal answer
Answer
Cross-platform subscription management, receipt validation, analytics, and A/B testing for paywalls.
Question
Why are subscription groups important?
Click to reveal answer
Answer
They ensure users can only have one active subscription per group, preventing users from subscribing to multiple tiers simultaneously.
Question
What is a key retention strategy for subscription apps?
Click to reveal answer
Answer
Optimize onboarding to quickly demonstrate value, track engagement, and send re-engagement notifications for at-risk users.
Revision Notes
Key Takeaways
- 1. Auto-renewable subscriptions renew automatically until cancelled
- 2. Subscription groups prevent multiple active subscriptions per tier
- 3. RevenueCat simplifies cross-platform subscription management
- 4. Optimize onboarding and trial periods for better retention
Interview Tips
- • Explain how subscription groups work and why they exist
- • Discuss the tradeoffs between StoreKit and RevenueCat
- • Describe strategies for reducing subscription churn
- • Know how to check subscription entitlements with StoreKit 2
Cheat Sheet
Subscriptions Quick Reference
- Auto-renewable: weekly, monthly, annually
- Subscription groups: one active per group
- RevenueCat: cross-platform management
- Transaction.currentEntitlements: active subscriptions
- Trial: 3-7 days ideal
- Retention: onboarding + engagement tracking