StoreKit — StoreView
This article is extracted from the chat log with AI. Please identify it with caution.

StoreViewStoreKit 框架中的一个 SwiftUI 组件,专门用于展示应用内购买商品(包括一次性购买、消耗型商品和订阅)的集合视图。它比 ProductView 更强大,支持以列表、网格或其他布局形式展示多个商品,并提供统一的购买管理接口。


核心功能 #

  1. 多商品展示
    支持通过商品 ID 数组或 Product 对象数组,自动加载并展示多个商品。
  2. 自适应布局
    默认根据商品类型(如订阅与非订阅)自动调整界面风格,也支持自定义布局。
  3. 订阅组管理
    专门针对订阅商品,支持展示订阅组(Subscription Group)的选项(如月度/年度计划)。
  4. 与 StoreKit 深度集成
    自动处理商品加载、购买流程、错误提示和交易验证,减少开发者代码量。

基本用法 #

1. 初始化方式 #

通过 商品 ID 数组Product 对象数组 初始化:

import SwiftUI
import StoreKit

// 通过商品 ID 初始化(推荐)
struct StoreViewDemo: View {
    var body: some View {
        StoreView(ids: ["com.yourcompany.product1", "com.yourcompany.product2"])
    }
}

// 通过 Product 对象初始化(需预先加载商品信息)
struct StoreViewDemo: View {
    let products: [Product] // 通过 Product.products(for:) 加载
    
    var body: some View {
        StoreView(products: products)
    }
}

2. 订阅组展示 #

若商品包含订阅组,StoreView 会自动分组展示选项:

StoreView(ids: ["subscription_monthly", "subscription_yearly"])
// 自动将同一订阅组的商品合并展示(如选择月度或年度计划)

高级配置 #

1. 设置展示样式 #

通过 storeViewStyle 修改布局样式(iOS 17+):

StoreView(ids: ["product1", "product2"])
    .storeViewStyle(.grid) // 支持 .grid(网格)、.collection(集合)、.default(默认)

2. 自定义订阅组名称 #

为订阅组设置本地化名称:

StoreView(ids: ["subscription_monthly", "subscription_yearly"])
    .subscriptionGroupLabel("Premium Access Plans") // 设置订阅组标题

3. 处理购买结果 #

通过 onInAppPurchaseCompletion 监听购买状态:

StoreView(ids: ["product1", "product2"])
    .onInAppPurchaseCompletion { product, result in
        switch result {
        case .success(.success(let transaction)):
            print("购买成功: \(transaction.productID)")
        case .failure(let error):
            print("购买失败: \(error.localizedDescription)")
        default:
            break
        }
    }

ProductView 的对比 #

特性ProductViewStoreView
展示对象单个商品多个商品或订阅组
布局复杂度简单(单一商品)复杂(支持网格、列表等布局)
订阅组支持自动分组展示订阅选项
适用场景展示独立商品(如游戏货币)展示完整商店页面(如订阅计划)

代码示例:完整商店页面 #

struct FullStoreView: View {
    @State private var errorMessage: String?
    
    var body: some View {
        NavigationStack {
            StoreView(ids: ["subscription_monthly", "coins_100", "premium_theme"])
                .storeViewStyle(.collection) // 集合视图样式
                .subscriptionGroupLabel("订阅计划")
                .navigationTitle("应用商店")
                .toolbar {
                    Button("恢复购买") {
                        Task { try? await AppStore.sync() }
                    }
                }
                .alert("错误", isPresented: .constant(errorMessage != nil)) {
                    Button("确定", role: .cancel) { }
                } message: {
                    Text(errorMessage ?? "")
                }
        }
    }
}

使用注意事项 #

  1. 商品审核状态
    确保所有商品在 App Store Connect 中已审核通过,否则 StoreView 无法加载。
  2. 最低系统要求
    • iOS 17.0+
    • macOS 14.0+
  3. 沙盒测试
    在 Xcode 中使用 StoreKit Configuration 文件模拟购买流程,或在真机上使用沙盒账户测试。

常见问题 #

  • 商品未显示?
    检查商品 ID 是否正确,确保网络连接正常,且商品在 App Store Connect 中已批准。
  • 如何自定义商品单元格?
    StoreView 的 UI 深度集成系统样式,若需完全自定义,仍需使用 ProductView 或手动实现。
  • 支持跨平台吗?
    是,StoreView 在 iOS、macOS、visionOS 等平台上自动适配样式。

官方文档扩展 #

通过 StoreView,开发者可以快速构建符合苹果设计规范的多商品商店界面,尤其适合需要展示订阅选项的应用(如流媒体服务、付费会员等)。

对比 ProductView #

To achieve a custom layout, you can compose ProductView instances with other container views instead of using the StoreView.

ProductViewStoreView 是 StoreKit 2 中两个不同的 SwiftUI 组件,分别针对不同的应用内购买(IAP)场景设计。以下是它们的核心区别和使用场景对比:


1. 功能定位 #

ProductViewStoreView
目标对象单个商品多个商品或订阅组
核心能力展示单个商品的基本信息和购买按钮展示商品集合,支持复杂布局(如网格、列表)和订阅组管理
自动化程度自动加载商品信息、格式化和购买逻辑自动处理多商品加载、布局适配、订阅组分类

2. 使用场景 #

ProductView #

  • 适用场景

    • 需要展示单个商品(如游戏货币、一次性解锁功能)。
    • 快速集成简单购买按钮,无需复杂界面设计。
    • 在应用内分散的入口展示商品(如设置页中的“升级到高级版”按钮)。
  • 示例代码

    // 展示单个商品
    struct UnlockProView: View {
        var body: some View {
            VStack {
                Text("升级到专业版")
                ProductView(id: "com.yourapp.pro_version")
                    .productViewStyle(.compact)
            }
        }
    }
    

StoreView #

  • 适用场景

    • 需要展示多个商品或订阅计划(如订阅服务的月度/年度选项、商品包)。
    • 构建完整的应用商店页面,支持复杂布局(如网格、列表)。
    • 需要自动管理订阅组(Subscription Group)的展示和选择逻辑。
  • 示例代码

    // 展示多个商品和订阅组
    struct SubscriptionStore: View {
        var body: some View {
            StoreView(ids: ["subscription_monthly", "subscription_yearly", "coins_100"])
                .storeViewStyle(.grid) // 网格布局
                .subscriptionGroupLabel("订阅计划") // 自定义订阅组标题
        }
    }
    

3. 布局与定制化 #

ProductViewStoreView
默认布局垂直堆叠的商品信息+购买按钮自动根据商品类型分组(如订阅与非订阅)
布局控制简单调整尺寸和按钮样式支持 .grid(网格)、.collection(集合)、.default(列表)
UI 定制性较低(依赖系统样式)中等(可通过修饰符调整标题、布局,但单元格内容不可自定义)

4. 订阅支持 #

ProductViewStoreView
订阅组展示不支持(需手动实现)自动将同一订阅组的商品合并展示,并提供选择界面(如月度 vs 年度)
续订提示自动显示订阅续订周期和优惠信息

5. 代码复杂度 #

  • ProductView
    适用于极简场景,几行代码即可展示商品:

    ProductView(id: "product_id")
        .onInAppPurchaseCompletion { product, result in /* ... */ }
    
  • StoreView
    适合多商品场景,但需注意商品加载和布局配置:

    StoreView(ids: ["product1", "product2"])
        .storeViewStyle(.collection)
        .subscriptionGroupLabel("套餐选项")
    

6. 系统要求 #

ProductViewStoreView
最低系统版本iOS 15.0+、macOS 12.0+iOS 17.0+、macOS 14.0+

何时选择? #

  • 使用 ProductView 的情况

    • 只需展示单个商品。
    • 需要快速集成购买功能,不追求复杂界面。
    • 支持较低系统版本(iOS 15/macOS 12)。
  • 使用 StoreView 的情况

    • 需要展示多个商品或订阅组。
    • 希望自动管理订阅选项的展示和购买流程。
    • 目标用户系统为 iOS 17/macOS 14 或更高。

混合使用示例 #

结合两者,实现灵活布局:

struct HybridStoreView: View {
    var body: some View {
        VStack {
            // 用 StoreView 展示订阅组
            StoreView(ids: ["subscription_monthly", "subscription_yearly"])
                .subscriptionGroupLabel("订阅计划")
            
            // 用 ProductView 展示独立商品
            ProductView(id: "coins_100")
                .productViewStyle(.compact)
        }
    }
}

总结 #

  • 简单性 vs 全面性ProductView 轻量但功能单一,StoreView 复杂但覆盖多商品场景。
  • 订阅场景优先:若涉及订阅,优先使用 StoreView 以利用其自动分组功能。
  • 版本兼容性:考虑用户设备的系统版本,选择兼容的组件。
本文共 2432 字,创建于 May 4, 2025
相关标签: Xcode, ByAI, SwiftUI, StoreKit