App启动时如何通过application(:didFinishLaunchingWithOptions:)调用SwiftyStoreKit内购函数?
实现SwiftyStoreKit启动时注册交易观察者的详细步骤
没问题,这就给你一步步梳理怎么在App启动时设置SwiftyStoreKit的交易观察者,完全贴合苹果的官方建议,确保不会漏掉任何支付队列通知。
一、先确认SwiftyStoreKit已正确集成
既然你已经用CocoaPods引入了SwiftyStoreKit,先确保Podfile里有对应的依赖,并且执行过pod install,项目里能正常import SwiftyStoreKit即可。
二、UIKit项目(AppDelegate)实现方式
如果你的项目还是用传统的AppDelegate生命周期,直接在application(_:didFinishLaunchingWithOptions:)方法里调用completeTransactions()就行,这是苹果推荐的启动时注册时机:
import UIKit import SwiftyStoreKit @main class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 启动时立即注册交易观察者,处理未完成的交易 SwiftyStoreKit.completeTransactions(atomically: true) { purchases in for purchase in purchases { switch purchase.transaction.transactionState { case .purchased, .restored: // 确认需要收尾的交易,手动完成(更安全) if purchase.needsFinishTransaction { SwiftyStoreKit.finishTransaction(purchase.transaction) } // 这里添加你的业务逻辑:比如解锁功能、给用户发通知 print("交易成功完成:\(purchase.productId)") case .failed: // 处理交易失败的情况,比如提示用户 if let error = purchase.error { print("交易失败:\(error.localizedDescription)") } case .purchasing, .deferred: // 交易中或等待家长审核的状态,暂时无需处理 break @unknown default: break } } } return true } // 其他AppDelegate方法... }
三、SwiftUI项目(App结构体)实现方式
如果是SwiftUI的App生命周期,推荐在App结构体的init()方法里执行注册逻辑,确保App一启动就完成观察者注册:
import SwiftUI import SwiftyStoreKit @main struct MyAwesomeApp: App { init() { // 启动时初始化交易观察者 SwiftyStoreKit.completeTransactions(atomically: true) { purchases in for purchase in purchases { switch purchase.transaction.transactionState { case .purchased, .restored: if purchase.needsFinishTransaction { SwiftyStoreKit.finishTransaction(purchase.transaction) } // 处理解锁逻辑,比如更新UserDefaults或通知ViewModel case .failed: // 处理失败场景 break case .purchasing, .deferred: break @unknown default: break } } } } var body: some Scene { WindowGroup { ContentView() } } }
四、优化建议:封装交易处理逻辑
为了代码更整洁易维护,建议把IAP相关逻辑封装到单例管理器里,比如:
import SwiftyStoreKit class IAPManager { static let shared = IAPManager() // 对外暴露的启动注册方法 func setupTransactionObserver() { SwiftyStoreKit.completeTransactions(atomically: true) { purchases in self.handleCompletedTransactions(purchases) } } // 私有方法:统一处理交易结果 private func handleCompletedTransactions(_ purchases: [Purchase]) { for purchase in purchases { switch purchase.transaction.transactionState { case .purchased, .restored: if purchase.needsFinishTransaction { SwiftyStoreKit.finishTransaction(purchase.transaction) } // 根据产品ID分发不同的解锁逻辑 switch purchase.productId { case "com.yourapp.premium_subscription": UserDefaults.standard.set(true, forKey: "isPremiumUser") // 可以发送通知让UI更新 NotificationCenter.default.post(name: NSNotification.Name("PremiumUnlocked"), object: nil) default: break } case .failed: if let error = purchase.error { print("IAP Error: \(error.localizedDescription)") } case .purchasing, .deferred: break @unknown default: break } } } }
然后在启动时只需调用一行代码:
// UIKit在AppDelegate里 IAPManager.shared.setupTransactionObserver() // SwiftUI在App结构体init里 IAPManager.shared.setupTransactionObserver()
关键注意事项
- 苹果要求必须在App启动时就注册观察者,这样才能捕获所有支付队列的通知,包括App在后台完成的交易,绝对不能把这个调用放到某个页面的
viewDidLoad里。 - 一定要调用
finishTransaction,否则未完成的交易会一直留在队列里,下次启动App会被重复处理,导致逻辑混乱。
内容的提问来源于stack exchange,提问作者Jared L.
相关产品推荐
相关产品推荐

