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

如何通过StoreKit配置文件检测iOS应用内购是否成功?

解决方案:在StoreKit配置测试中检测本地购买状态

当使用StoreKit配置文件进行内购测试时,由于测试购买不会同步到你的私有服务器,你可以直接通过标准StoreKit API读取本地的交易或授权状态,替代服务器校验。以下是针对不同StoreKit版本的实现方式:

StoreKit 2(iOS 15+,推荐)

StoreKit 2提供了异步获取当前用户有效授权的API,可直接读取测试环境下的本地购买记录:

import StoreKit

/// 检查是否存在有效目标购买项
func hasActiveTargetPurchase() async -> Bool {
    // 遍历当前所有有效授权(包括订阅和非消耗型购买)
    for await entitlement in Transaction.currentEntitlements {
        // 替换为你的目标产品ID
        guard entitlement.productID == "com.yourapp.premium_subscription" else {
            continue
        }
        
        // 若为订阅,可额外校验是否在有效期内
        if case .subscription(let subscription) = entitlement.productType {
            return subscription.expirationDate > Date()
        }
        
        // 非订阅类购买(如非消耗型)直接返回true
        return true
    }
    return false
}

调用示例:

// 在视图逻辑中使用
Task {
    let hasPurchase = await hasActiveTargetPurchase()
    if hasPurchase {
        // 展示下一个视图
        navigateToNextView()
    } else {
        // 展示付费墙
        showPaywall()
    }
}

StoreKit 1(兼容iOS 14及以下)

如果需要兼容旧系统,可以通过交易队列或本地收据解析来判断:

方式1:读取本地交易队列

import StoreKit

func hasActiveTargetPurchase() -> Bool {
    let paymentQueue = SKPaymentQueue.default()
    // 遍历所有未完成或已完成的交易
    for transaction in paymentQueue.transactions {
        guard transaction.payment.productIdentifier == "com.yourapp.premium_subscription" else {
            continue
        }
        
        // 已购买或已恢复的交易视为有效
        if transaction.transactionState == .purchased || transaction.transactionState == .restored {
            // 订阅类可额外解析有效期(需从transaction的receipt中提取)
            return true
        }
    }
    return false
}

方式2:解析本地收据

你可以解析App Store本地收据(测试环境下会生成测试收据),推荐使用第三方库如SwiftyStoreKit简化解析:

import SwiftyStoreKit

func hasActiveTargetPurchase() -> Bool {
    let result = SwiftyStoreKit.verifyReceipt(using: .sandbox)
    switch result {
    case .success(let receipt):
        // 检查目标订阅是否有效
        let subscriptionStatus = SwiftyStoreKit.verifySubscription(
            productId: "com.yourapp.premium_subscription",
            inReceipt: receipt
        )
        return subscriptionStatus.isActive
    case .error:
        return false
    }
}

环境区分优化

为了避免测试逻辑影响生产环境,可以通过编译标记区分调试和生产模式:

#if DEBUG
// 测试环境:优先使用本地StoreKit API判断
func checkPurchaseStatus() async -> Bool {
    return await hasActiveTargetPurchase()
}
#else
// 生产环境:调用私有服务器校验
func checkPurchaseStatus() async -> Bool {
    return await verifySubscriptionOnServer()
}
#endif

核心逻辑:StoreKit配置文件生成的测试购买会写入本地的交易队列和收据中,标准StoreKit API可以直接读取这些测试数据,无需依赖虚构的StoreKitTestEnvironment对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 14:05:30