Apple StoreKit 2 开发指南
StoreKit 2 是 Apple 推出的新一代内购开发框架(适配 iOS 15+/macOS 12+/tvOS 15+),相比初代大幅简化内购流程、强化异步处理与用户体验,是开发 App 内购(IAP)的首选方案。以下聚焦核心流程、关键 API 与实战要点,适配 Swift 开发场景。
一、核心优势
- 简化流程:用
ProductTransaction等结构化 API 替代初代繁杂的代理回调,代码更简洁; - 异步安全:全流程基于
async/await异步编程,避免回调地狱,适配现代 Swift 开发; - 用户体验优化:支持内购恢复、价格本地化、交易状态实时追踪,减少用户操作成本;
- 合规适配:内置收据验证、退款处理逻辑,符合 App Store 审核规范。
二、开发前置准备
1. 开发者后台配置
- 登录 App Store Connect,创建 App 内购项目(消耗型、非消耗型、订阅型),填写产品 ID、价格、描述等信息;
- 开启 “App 内购买项目” 权限,配置沙盒测试账号(用于测试内购流程,避免真实扣费)。
2. 工程配置
- Xcode 版本 ≥ 13.2(需支持 iOS 15+ 部署目标);
- 项目
Signing & Capabilities中开启In-App Purchase能力; - 导入框架:
import StoreKit。
三、核心开发流程
1. 加载内购产品
通过产品 ID 加载 App Store 配置的内购项目,获取价格、描述等信息:
swift
// 定义产品 ID(需与 App Store Connect 一致)
let productIDs = ["com.xxx.app.consumable", "com.xxx.app.subscription.monthly"]
// 加载产品
func fetchProducts() async throws -> [Product] {
let products = try await Product.products(for: productIDs)
// 按产品类型/价格排序(可选)
return products.sorted { $0.price < $1.price }
}
// 调用示例
Task {
do {
let products = try await fetchProducts()
// 展示到 UI(如价格、购买按钮)
for product in products {
print("产品名:\(product.displayName),价格:\(product.price)")
}
} catch {
print("加载产品失败:\(error.localizedDescription)")
}
}
2. 发起购买请求
调用
purchase() 方法发起购买,处理交易结果:swift
func purchaseProduct(_ product: Product) async throws -> Transaction? {
// 发起购买
let result = try await product.purchase()
switch result {
case .success(let verification):
// 验证交易有效性
switch verification {
case .unverified(let transaction, let error):
print("交易验证失败:\(error.localizedDescription)")
return nil
case .verified(let transaction):
// 完成交易(必须调用,否则交易状态异常)
await transaction.finish()
return transaction
}
case .userCancelled:
print("用户取消购买")
return nil
case .pending:
print("交易待处理(如家长审核)")
return nil
@unknown default:
return nil
}
}
// 调用示例(绑定到购买按钮点击事件)
Task {
if let product = products.first { // 取第一个产品示例
do {
let transaction = try await purchaseProduct(product)
if transaction != nil {
print("购买成功,解锁功能")
// 此处处理解锁付费功能逻辑
}
} catch {
print("购买失败:\(error.localizedDescription)")
}
}
}
3. 恢复已购项目
用户重装 App / 切换设备时,恢复过往购买(重点适配非消耗型 / 订阅型内购):
swift
func restorePurchases() async {
do {
// 恢复所有已购交易
for await result in Transaction.currentEntitlements {
switch result {
case .unverified(let transaction, let error):
print("恢复验证失败:\(error)")
case .verified(let transaction):
// 解锁对应功能
print("恢复成功:\(transaction.productID)")
await transaction.finish()
}
}
} catch {
print("恢复失败:\(error.localizedDescription)")
}
}
4. 验证交易(可选但推荐)
本地验证交易有效性,或调用 App Store 服务器 API 验证(避免篡改):
swift
// 本地基础验证(简化版)
func verifyTransaction(_ transaction: Transaction) -> Bool {
guard transaction.revocationDate == nil else {
// 交易已撤销(退款),锁定功能
return false
}
return true
}
四、关键注意事项
- 沙盒测试:必须使用沙盒账号测试,真实账号会触发真实扣费;测试订阅时,可通过 App Store Connect 加速订阅周期(缩短测试时长);
- 交易状态:所有交易必须调用
finish()方法,否则会重复触发; - 订阅管理:订阅型内购需监听
Transaction.updates事件,处理订阅续订、过期、取消等状态; - 审核合规:App 内需提供 “恢复购买” 按钮,订阅型内购需清晰展示价格、续订规则,避免误导用户;
- 错误处理:覆盖网络异常、用户取消、家长控制、地区限制等场景,给出友好提示。
五、常见问题
- 产品加载失败:检查产品 ID 与 App Store Connect 一致、网络正常、沙盒环境配置正确;
- 购买提示 “无法连接到 App Store”:确认设备登录沙盒账号、网络无代理、Xcode 签名配置正确;
- 订阅恢复失败:确保
Transaction.currentEntitlements遍历完整,处理revocationDate非空场景。
总结
StoreKit 2 以
async/await 为核心,大幅降低内购开发复杂度。核心流程可总结为:配置产品 ID → 加载产品 → 发起购买 → 验证交易 → 解锁功能 → 处理恢复 / 退款,重点关注沙盒测试与合规适配,即可快速完成内购功能开发。

浙公网安备 33010602011771号