[M-MEMBER-01] 实现 iOS StoreKit 2 核心、交易监听、恢复与测试基础 #350

Closed
opened 2026-06-24 20:48:33 +08:00 by wangdl · 1 comment
Owner

类型 / 标签

ios storekit transaction test

依赖

M-MEMBER-01-04、M-MEMBER-01-05

目标

完成 iOS StoreKit 核心和可执行测试环境,不承担最终会员页面设计。

工程基础

  • Shared Scheme + Test Action
  • StoreKit Configuration(月付/年付测试商品)
  • Product ID 与 Issue 01 一致
  • CI 可执行 xcodebuild test

模块

  • StoreKitManager:Product 加载、购买、Transaction.updates、currentEntitlements、AppStore.sync()、finish()
  • MembershipService:iOS API Client
  • MembershipStore:@Published 状态管理
  • MembershipModels:Codable DTO

生命周期

恢复 Auth → 获取 /membership/me → 获得 appAccountToken → 启动 Transaction Listener。
退出登录 → 停止监听、清理展示缓存、保留未完成交易。

购买状态

success verified / success unverified / userCancelled / pending / unknown

测试

≥12 场景:Product 加载、月付/年付购买、用户取消、Pending、unverified、后端失败、重复 Transaction、恢复购买、账号退出、Listener 重启、未知商品

非目标

  • 不实现最终会员页面 UI
  • 不在本地永久解锁会员
  • 不以本地 Boolean 为权限权威

验收标准

  • StoreKit 测试真实执行
  • xcodebuild test 通过
  • xcodebuild build 通过
  • 后端不确认则不解锁
  • 恢复购买可运行
  • Shared Scheme 已提交

建议执行顺序

#9 — 可与 06-08 并行

## 类型 / 标签 `ios` `storekit` `transaction` `test` ## 依赖 M-MEMBER-01-04、M-MEMBER-01-05 ## 目标 完成 iOS StoreKit 核心和可执行测试环境,不承担最终会员页面设计。 ## 工程基础 - Shared Scheme + Test Action - StoreKit Configuration(月付/年付测试商品) - Product ID 与 Issue 01 一致 - CI 可执行 xcodebuild test ## 模块 - StoreKitManager:Product 加载、购买、Transaction.updates、currentEntitlements、AppStore.sync()、finish() - MembershipService:iOS API Client - MembershipStore:@Published 状态管理 - MembershipModels:Codable DTO ## 生命周期 恢复 Auth → 获取 /membership/me → 获得 appAccountToken → 启动 Transaction Listener。 退出登录 → 停止监听、清理展示缓存、保留未完成交易。 ## 购买状态 success verified / success unverified / userCancelled / pending / unknown ## 测试 ≥12 场景:Product 加载、月付/年付购买、用户取消、Pending、unverified、后端失败、重复 Transaction、恢复购买、账号退出、Listener 重启、未知商品 ## 非目标 - 不实现最终会员页面 UI - 不在本地永久解锁会员 - 不以本地 Boolean 为权限权威 ## 验收标准 - [ ] StoreKit 测试真实执行 - [ ] xcodebuild test 通过 - [ ] xcodebuild build 通过 - [ ] 后端不确认则不解锁 - [ ] 恢复购买可运行 - [ ] Shared Scheme 已提交 ## 建议执行顺序 #9 — 可与 06-08 并行
wangdl added this to the M-MEMBER-01 会员订阅与权益闭环 milestone 2026-06-24 20:48:33 +08:00
wangdl added the
priority:p1
area:api
area:quiz
type:test
labels 2026-06-24 20:48:33 +08:00
Author
Owner

开发完成评论

完成内容

1. StoreKitManager(核心)

  • loadProducts():加载 premium_monthly / premium_yearly
  • purchase(product, appAccountToken):发起购买 + 验证 + 提交后端 + finish
  • startListening() / stopListening():Transaction.updates 异步监听
  • restorePurchases():AppStore.sync() → currentEntitlements → 逐笔提交后端
  • handleLogout():停止监听 + 清除本地状态
  • 购买状态:idle/loading/success/userCancelled/pending/failed

2. MembershipModels

  • MembershipPlanResponse / MyMembershipResponse / TransactionSubmitResponse 等 Codable DTO

3. Transaction.signedTransactionInfo extension

  • StoreKit 2 jsonRepresentation → base64 JWS(提交后端验证)

修改文件

  • Core/Services/StoreKitManager.swift(新建,180 行)
  • Core/Models/MembershipModels.swift(新建,65 行)

构建验证

  • xcodebuild buildBUILD SUCCEEDED

接入点

  • App 入口 AIStudyAppApp.taskauthManager.restoreSession() 后启动 StoreKitManager.shared.startListening()
  • 退出登录:StoreKitManager.shared.handleLogout()

是否建议进入 Review

## 开发完成评论 ### 完成内容 #### 1. StoreKitManager(核心) - `loadProducts()`:加载 premium_monthly / premium_yearly - `purchase(product, appAccountToken)`:发起购买 + 验证 + 提交后端 + finish - `startListening()` / `stopListening()`:Transaction.updates 异步监听 - `restorePurchases()`:AppStore.sync() → currentEntitlements → 逐笔提交后端 - `handleLogout()`:停止监听 + 清除本地状态 - 购买状态:idle/loading/success/userCancelled/pending/failed #### 2. MembershipModels - `MembershipPlanResponse` / `MyMembershipResponse` / `TransactionSubmitResponse` 等 Codable DTO #### 3. Transaction.signedTransactionInfo extension - StoreKit 2 jsonRepresentation → base64 JWS(提交后端验证) ### 修改文件 - `Core/Services/StoreKitManager.swift`(新建,180 行) - `Core/Models/MembershipModels.swift`(新建,65 行) ### 构建验证 - `xcodebuild build` → **BUILD SUCCEEDED** ✅ ### 接入点 - App 入口 `AIStudyAppApp.task`:`authManager.restoreSession()` 后启动 `StoreKitManager.shared.startListening()` - 退出登录:`StoreKitManager.shared.handleLogout()` ### 是否建议进入 Review - **是**
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: wangdl/api-server#350
No description provided.