Xcode 中的 StoreKit 测试功能介绍
Introducing StoreKit Testing in Xcode
2020年6月23日
一句话判断
Xcode 12 终于内置了 StoreKit 测试环境——不用再创建沙盒测试账号、不用跑 App Store Connect 配置,直接在 Xcode 里模拟购买、退款、订阅续期,内购调试效率直接翻倍。
这场 Session 讲了什么
内购(In-App Purchase)一直是 iOS 开发中调试最痛苦的环节之一。之前的流程是:在 App Store Connect 创建产品 -> 创建沙盒测试账号 -> 用沙盒账号在真机上测试 -> 等待服务器同步。Xcode 12 的 StoreKit Testing 彻底改变了这个流程。
现在你可以在 Xcode 中创建一个 StoreKit Configuration File(.storekit 文件),在里面定义所有内购产品(消耗型、非消耗型、自动续期订阅)。运行 app 时选择使用这个本地配置文件作为 StoreKit 后端,所有购买操作都在本地完成,不需要网络,不需要沙盒账号。
Session 演示了如何创建 StoreKit Configuration File、如何在 Xcode 的 StoreKit 管理面板中手动触发各种购买状态(购买成功、购买失败、退款、订阅过期、计费重试等)、以及如何自动化测试内购流程。
值得深挖的点
StoreKit Configuration File 是核心
这是一个 JSON 格式的配置文件,定义了所有你要测试的产品。格式如下:每个产品有 ID、类型、价格、订阅组等属性。你可以在文件中定义多组产品来模拟不同地区的价格。这个文件可以提交到 Git,团队所有人共享同一套内购测试配置。
管理面板的时间控制
对于订阅类内购,最头疼的是测试续期——自动续期订阅的续期时间通常是 1 个月到 1 年,你不可能等那么久。Xcode 的 StoreKit 管理面板允许你手动「快进」时间:点击「Renew Subscription」立即触发续期,点击「Expire」立即让订阅过期。还可以模拟「Billing Retry」场景(用户卡里没钱,Apple 会重试扣费)。
代码片段
import StoreKit
// 标准的 StoreKit 购买代码,在 Xcode StoreKit Testing 中可以直接运行
class StoreManager: NSObject, SKProductsRequestDelegate, SKPaymentTransactionObserver {
var products: [SKProduct] = []
func fetchProducts() {
let request = SKProductsRequest(productIdentifiers: Set([
"com.app.premium.monthly",
"com.app.premium.yearly",
"com.app.coinpack100"
]))
request.delegate = self
request.start()
}
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
products = response.products
for product in products {
print("产品: \(product.localizedTitle), 价格: \(product.price)")
}
}
func purchase(_ product: SKProduct) {
let payment = SKPayment(product: product)
SKPaymentQueue.default().add(payment)
}
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
switch transaction.transactionState {
case .purchased:
print("购买成功: \(transaction.payment.productIdentifier)")
SKPaymentQueue.default().finishTransaction(transaction)
case .failed:
print("购买失败: \(transaction.error?.localizedDescription ?? "")")
SKPaymentQueue.default().finishTransaction(transaction)
case .restored:
print("恢复购买")
SKPaymentQueue.default().finishTransaction(transaction)
case .deferred:
print("等待家长审批")
default:
break
}
}
}
}
最佳实践
- 把 StoreKit Configuration File 加入版本控制。这是团队共享的测试配置,每个人的测试数据一致,内购 bug 才能复现。
- 用 Xcode 的 StoreKit 管理面板测试边界场景。正常购买流程跑通后,重点测试:购买失败恢复、订阅过期后的内容降级、退款后撤销功能、计费重试中间态。这些是用户投诉最多的场景。
- 写 UI 测试覆盖内购流程。Xcode 的 StoreKit Testing 支持在 XCTest 中使用,可以用
SKTestSession编程控制购买状态,实现完全自动化的内购流程测试。
还有什么值得关注
- StoreKit Testing 支持 StoreKit 2(iOS 15+)的测试,是向前兼容的。
- 在 Xcode 的 Scheme Editor 中选择 StoreKit Configuration File:
Edit Scheme > Run > Options > StoreKit Configuration。 .storekit文件可以导出为 App Store Connect 的产品配置,减少重复配置工作。