Generates StoreKit 2 subscription paywall with modern SwiftUI views. Use when user wants to add subscriptions, paywall, or in-app purchases.
Generate a complete StoreKit 2 subscription paywall with modern SwiftUI views, subscription status tracking, and proper purchase handling.
Use this skill when the user:
Search for existing StoreKit:
Glob: **/*Store*.swift, **/*Purchase*.swift, **/*Subscription*.swift
Grep: "import StoreKit" or "Product.products"
If found, ask user:
Latest StoreKit Updates (iOS 18.4+):
SubscriptionOfferView - New SwiftUI view for merchandising subscriptionssubscriptionStatusTask modifier for tracking subscription stateTransaction.currentEntitlements(for:) - New API for entitlementsRenewalInfo enhancements for expiration reasonsAsk user via AskUserQuestion:
Subscription tiers? (multi-select)
Features needed?
UI style?
Generate these files:
StoreKitManager.swift - Product loading and purchasingSubscriptionStatus.swift - Status trackingPaywallView.swift - Full paywall UISubscriptionButton.swift - Individual plan buttonProducts.swift - Product ID constantsCheck project structure:
Sources/ exists → Sources/Store/App/ exists → App/Store/Store/com.yourapp.subscription.monthlycom.yourapp.subscription.yearlycom.yourapp.subscription.lifetimeCreate Products.storekit for local testing:
After generation, provide:
Sources/Store/
├── StoreKitManager.swift # Product loading & purchasing
├── SubscriptionStatus.swift # Status enum & tracking
├── Products.swift # Product ID constants
└── Views/
├── PaywallView.swift # Full paywall screen
├── SubscriptionButton.swift # Plan selection button
└── SubscriptionOfferCard.swift # New iOS 18.4+ view
App Entry Point:
@main
struct MyApp: App {
@State private var subscriptionStatus: SubscriptionStatus = .unknown
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.subscriptionStatus, subscriptionStatus)
.subscriptionStatusTask(for: "your.group.id") { statuses in
subscriptionStatus = SubscriptionStatus.from(statuses)
}
}
}
}
Show Paywall:
struct ContentView: View {
@State private var showPaywall = false
@Environment(\.subscriptionStatus) var status
var body: some View {
VStack {
if status != .subscribed {
Button("Upgrade to Pro") {
showPaywall = true
}
}
}
.sheet(isPresented: $showPaywall) {
PaywallView()
}
}
}
New iOS 18.4+ SubscriptionOfferView:
// Simple merchandising view
SubscriptionOfferView(productID: "com.app.subscription.monthly")
.prefersPromotionalIcon(true)
.subscriptionOfferViewDetailAction {
showPaywall = true
}
Create StoreKit Configuration:
Edit Scheme:
Test Purchases:
Test Scenarios: