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

SwiftUI中StoreKit 2消耗型内购中断交易追踪及车辆关联方案

解决方案

要实现消耗型内购fuel87与特定车辆的绑定追踪,同时处理交易中断场景,需要从购买请求关联车辆标识、中断交易恢复匹配、交付逻辑定向绑定三个核心环节入手:

1. 给购买函数添加车辆标识参数

修改原购买函数,让它接收选中车辆的唯一ID(比如vehicleId: String),在发起购买时就明确要绑定的目标车辆,同时临时存储交易与车辆的关联关系,避免中断后丢失对应信息:

func purchase(_ product: Product, forVehicleId vehicleId: String) async throws -> Transaction? {
    // 发起购买请求
    let result = try await product.purchase()

    switch result {
    case .success(let verification):
        let transaction = try checkVerified(verification)
        // 交付前先绑定车辆
        await deliverFuelToVehicle(transaction: transaction, vehicleId: vehicleId)
        await transaction.finish()
        return transaction
    case .pending(let transaction):
        // 存储pending交易与车辆的关联,用于后续恢复
        if let transactionId = transaction.id {
            UserDefaults.standard.set(vehicleId, forKey: "PendingFuelTransaction_\(transactionId)")
        }
        return transaction
    case .userCancelled:
        return nil
    default:
        return nil
    }
}

// 定向交付燃料到指定车辆
private func deliverFuelToVehicle(transaction: Transaction, vehicleId: String) async {
    // 替换为你的业务逻辑:给vehicleId对应的车辆添加fuel87
    // 示例:
    // if let vehicle = vehicleStore.getVehicleById(vehicleId) {
    //     vehicle.addFuel(type: .fuel87)
    //     vehicleStore.saveVehicles()
    // }
}

2. 处理中断交易的恢复逻辑

交易中断(如APP关闭、来电)后,StoreKit会在APP重启或恢复活跃时推送未完成的交易更新。需要监听这些更新,并通过之前存储的关联关系找到对应的车辆:

监听交易更新

在你的StoreKit管理类中添加监听逻辑:

func startTransactionUpdates() {
    Task {
        for await update in Transaction.updates {
            do {
                let transaction = try checkVerified(update)
                // 仅处理fuel87的交易
                guard transaction.productID == "fuel87" else {
                    await transaction.finish()
                    return
                }
                
                // 从存储中获取绑定的车辆ID
                if let vehicleId = UserDefaults.standard.string(forKey: "PendingFuelTransaction_\(transaction.id)") {
                    await deliverFuelToVehicle(transaction: transaction, vehicleId: vehicleId)
                    // 交付完成后删除临时存储
                    UserDefaults.standard.removeObject(forKey: "PendingFuelTransaction_\(transaction.id)")
                }
                
                await transaction.finish()
            } catch {
                // 处理验证失败的情况
                await update.finish()
            }
        }
    }
}

APP启动时恢复未完成交易

在APP启动时(比如App结构体的init或主页面onAppear),主动获取所有未完成的交易,确保不会遗漏中断的购买:

func restorePendingTransactions() async {
    for await transaction in Transaction.all {
        do {
            let verifiedTransaction = try checkVerified(transaction)
            guard verifiedTransaction.productID == "fuel87", !verifiedTransaction.isFinished else {
                continue
            }
            
            if let vehicleId = UserDefaults.standard.string(forKey: "PendingFuelTransaction_\(verifiedTransaction.id)") {
                await deliverFuelToVehicle(transaction: verifiedTransaction, vehicleId: vehicleId)
                UserDefaults.standard.removeObject(forKey: "PendingFuelTransaction_\(verifiedTransaction.id)")
            }
            
            await verifiedTransaction.finish()
        } catch {
            await transaction.finish()
        }
    }
}

3. 关键注意事项

  • 车辆标识唯一性:确保每个车辆有唯一的vehicleId(比如UUID或服务器分配的ID),避免绑定错误。
  • 临时存储清理:交易完成或失败后,务必删除UserDefaults中对应的关联记录,避免冗余数据。
  • 云端同步(可选):如果你的APP有云端存储,建议将交易与车辆的绑定关系同步到服务器,防止本地数据丢失后无法恢复。

内容的提问来源于stack exchange,提问作者Jay Patel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 21:23:19