Skip to content

StoreKit 2 ProductView and StoreView (SwiftUI)

A SwiftUI guide for coding agents. Also covers productview, storeview, paywall ui ios, productviewstyle, storekit views, restore purchases button.

ProductView renders one purchasable product, loading and purchase flow included, from a single line. StoreView lays out a collection of them. Both ship with StoreKit 2's SwiftUI layer.

ProductView

One product id is enough. Styles come through productViewStyle: automatic (default), large, regular, or compact.

ProductView(id: "55667744")
    .productViewStyle(.compact)

prefersPromotionalIcon: true shows the promoted image uploaded to App Store Connect. An initializer overload swaps in your own icon view, with a placeholder while the product loads.

ProductView(id: "55667744") { _ in
    Image(systemName: "crown")
        .resizable()
        .scaledToFit()
} placeholderIcon: {
    ProgressView()
}
.productViewStyle(.large)

Custom Styles

Conform to ProductViewStyle for a fully custom presentation. makeBody receives a configuration carrying the loading state, the product, and a purchase() function to call from your own button.

struct CustomProductStyle: ProductViewStyle {
    func makeBody(configuration: Configuration) -> some View {
        switch configuration.state {
        case .loading:
            ProgressView()
        case .success(let product):
            Button {
                configuration.purchase()
            } label: {
                VStack {
                    Text(verbatim: product.displayName).font(.headline)
                    Text(verbatim: product.displayPrice)
                }
            }
            .buttonStyle(.borderedProminent)
        default:
            Text("Something goes wrong...")
        }
    }
}

The rendered views handle purchasing and observe refunds automatically; you compose layout, not transaction plumbing.

StoreView

StoreView(ids:) displays several products at once and adapts its layout to the platform, a grid on tvOS for example. The productViewStyle modifier still applies, and storeButton toggles the built-in buttons such as restore purchases.

StoreView(ids: ["123456789", "987654321"])
    .productViewStyle(.compact)
    .storeButton(.visible, for: .restorePurchases)

Use this guidance in your coding agent

Install the Better Design MCP once. Your agent then loads this page with one call.

get-swiftui-guide({ topic: "swiftui-mastering-storekit2-productview" })
claude mcp add --scope user better-design --transport http https://better-design.com/api/mcp --header "Authorization: Bearer <YOUR_API_KEY>"
Browse related design systems