You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:21:43