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 → 加載產品 → 發起購買 → 驗證交易 → 解鎖功能 → 處理恢復 / 退款,重點關注沙盒測試與合規適配,即可快速完成內購功能開發。