Skip to content
advanced Phase 13 · App Store & Distribution

Subscriptions & RevenueCat

Manage subscription lifecycle, retention, and analytics with RevenueCat or StoreKit 2.

55m
3 problems
Topic Progress 0%

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

  1. Go to App Store Connect > Your App > In-App Purchases
  2. Click the plus button and select Auto-Renewable Subscription
  3. Choose a subscription group
  4. 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?

Question 1 options

2. What is a benefit of using RevenueCat over direct StoreKit implementation?

Question 2 options

3. What is the ideal trial length for most subscription apps?

Question 3 options

4. What does Transaction.currentEntitlements return?

Question 4 options

Flashcards

Question

What is an auto-renewable subscription?

Answer

A subscription that automatically renews at regular intervals (weekly, monthly, annually) until the user cancels.

Question

What does RevenueCat simplify?

Answer

Cross-platform subscription management, receipt validation, analytics, and A/B testing for paywalls.

Question

Why are subscription groups important?

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?

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