StoreKit 2:如何验证有效订阅?

问题描述 投票:0回答:3

许多围绕 StoreKit 2 的 教程,甚至 Apple 自己的示例代码 都引用了“Xcode 中的 StoreKit 测试,这样您就可以构建并运行示例应用程序,而无需在 App Store Connect 中完成任何设置。该项目定义了应用程序内产品Products.storekit 文件中的 StoreKit 测试服务器。”我有一个已在 App Store Connect 中设置自动续订订阅的应用程序(从 SwiftyStoreKit 迁移到 StoreKit 2)...我如何设置此 StoreKitManager 类来检查活动订阅,而无需创建单独的

Products.plist
文件?下面的代码主要基于 Apple 的示例代码,结果是
Error Domain=ASDErrorDomain Code=509 "No active account"
,这很明显,因为我不知道如何将我的产品连接到 StoreKit 2 逻辑? 🤔

编辑:这是我的代码的要点

import Foundation
import StoreKit

typealias Transaction = StoreKit.Transaction

public enum StoreError: Error {
    case failedVerification
}

@available(watchOSApplicationExtension 8.0, *)
class WatchStoreManager: ObservableObject {
    
    var updateListenerTask: Task<Void, Error>? = nil
    
    init() {
        print("Init called in WatchStoreManager")
        //Start a transaction listener as close to app launch as possible so you don't miss any transactions.
        updateListenerTask = listenForTransactions()
    }
    
    deinit {
        updateListenerTask?.cancel()
    }
    
    func listenForTransactions() -> Task<Void, Error> {
        return Task.detached {
            //Iterate through any transactions that don't come from a direct call to `purchase()`.
            for await result in Transaction.updates {
                do {
                    let transaction = try self.checkVerified(result)
                    
                    print("we have a verified transacction")

                    //Deliver products to the user.
                    //TODO:
                    //await self.updateCustomerProductStatus()

                    //Always finish a transaction.
                    await transaction.finish()
                } catch {
                    //StoreKit has a transaction that fails verification. Don't deliver content to the user.
                    print("Transaction failed verification")
                }
            }
        }
    }
    
    func checkVerified<T>(_ result: VerificationResult<T>) throws -> T {
        //Check whether the JWS passes StoreKit verification.
        switch result {
        case .unverified:
            //StoreKit parses the JWS, but it fails verification.
            throw StoreError.failedVerification
        case .verified(let safe):
            //The result is verified. Return the unwrapped value.
            return safe
        }
    }
    
}
ios swift storekit auto-renewing storekit2
3个回答
1
投票

对我来说,我的 Xcode 项目的 Bundle id 与 appstoreconnect 的 Bundle id 不完全匹配。 我在 Xcode 上更改了它,但没有在 appstoreconnect 上更新。

奇怪的是,我的本地测试的配置存储文件同步得很好,一切正常。

一般来说(对于使用 StoreKit 2 进行沙箱测试)我当然会检查: -您已在 appstoreconnect 上创建了应用程序和应用内购买。 -您已同意 appstoreconnect 上的每项协议 - 协议、税收等。 - 产品标识符和捆绑 ID 匹配。

这就是我尝试解决这个问题、看到其他人的问题以及对他们有用的方法所得到的。希望有人能得到这个有用的!


0
投票

509:没有活跃帐户

表示用户未登录应用商店。前往

Settings -> Sign in to Your iPhone
并使用有效的 App Store 或沙盒帐户登录

编辑:我看到您已登录您的设备 - 这很奇怪。您提到您尚未链接您的产品。您需要使用类似于以下内容的内容从 App Store 获取产品。但我不希望您看到特定的错误消息...

    enum AppProduct: String, CaseIterable, Identifiable {
        case noAds = "MYUNIQUEIDENTIFIER_ESTABLISHEDIN_APPSTORECONNECT"

        var id: String {
            UUID().uuidString
        } // to make it Identifiable for use in a List

        static var allProductIds: [String] {
            return Self.allCases.map { $0.rawValue }
        } // convenience
    }


    @MainActor
    @discardableResult func fetchProducts() async throws -> [Product] {
        let products = try await Product.products(for: AppProduct.allProductIds) // this is the call that fetches products
        guard products.first != nil else { throw PurchaseError.unknown } // custom error
        self._storeProducts = products
        let fetchedProducts: [AppProduct] = products.compactMap {
            let appProduct = AppProduct(rawValue: $0.id)
            return appProduct
        }
        self.fetchedProducts = fetchedProducts
        try await checkPurchased()
        return products
    }

    private func checkPurchased() async throws {
        for product in _storeProducts {
            guard let state = await product.currentEntitlement else { continue }
            let transaction = try self.checkVerified(state)
            //Always finish a transaction.
            await transaction.finish()
        }
    }

当验证通过时,我正在 checkVerified 中设置购买状态...


0
投票

我到处查看,最后发现当您添加新订阅或更新某些内容时,您必须将其与 Xcode 中的产品“同步”。在工作区中的某个位置打开 .storekit 文件,左下角应该有一个刷新按钮,用于将 StoreKit 确认文件与 Apple Store Connect 中的内容同步。

© www.soinside.com 2019 - 2024. All rights reserved.