我正在尝试使用 StoreKit 2 为非消耗性产品设置应用内购买。如果您查看应用内购买的 App Store Connect / Xcode 配置文件,Apple 建议在提交之前测试 43 个错误条件。应用程序进行审查。问题是所有在线示例代码(包括 Apple 的)从未展示如何设置支持这些错误所需的代码。
具体来说,我正在寻求有关“加载产品”错误的帮助。在 Apple 对 products(for:) 的讨论下,它说: 如果任何标识符无效或 App Store 找不到它们,App Store 会将它们排除在返回值之外。 products(for:) 函数可以针对系统相关错误抛出 StoreKitError。 在我对加载产品错误的测试中,对于所有这些错误,我得到一个带有旋转轮(progressView())的空屏幕。
我目前在产品 catch 块 switch 语句中遇到各种错误,例如
Type '[Product]' has no member 'systemError'。它似乎无法识别我的 StoreKitError 枚举。
在下面的代码中,我没有显示我的所有 StoreModel。如果需要的话,我很乐意展示更多。
@MainActor final class StoreModel: ObservableObject {
enum StoreKitError {
case networkError(URLError)
case systemError(any Error)
case userCancelled
case notAvailableInStorefront
case notEntitled
case unknown
}
public enum PurchaseFinishedAction {
case dismissStore
case noAction
case displayError
}
func fetchProducts() async throws -> PurchaseFinishedAction {
let action: PurchaseFinishedAction
do {
products = try await Product.products(
for: productIDs)
} catch {
switch products {
case .networkError(URLError):
action = .displayError
case .systemError(any Error):
action = .displayError
case .userCancelled:
action = .noAction
case .notAvailableInStorefront:
action = .displayError
case .notEntitled:
action = .displayError
case .product.unknown:
action = .displayError
}
}
return action
}
StoreKit
,但这个示例代码可以为我编译。 另请注意
StoreKit
已经有 StoreKitError
无需重新声明它们,
不确定PurchaseFinishedAction
@MainActor final class StoreModel: ObservableObject {
@Published var products: [Product] = [] // <--- here
public enum PurchaseFinishedAction {
case dismissStore
case noAction
case displayError
case noStoreKitError // <--- here
}
func fetchProducts() async throws -> PurchaseFinishedAction {
var action = PurchaseFinishedAction.noStoreKitError // <--- here
do {
products = try await Product.products(for: ["com.example.productA"]) // productIDs
} catch {
if let err = error as? StoreKitError { // <--- here
switch err {
case .networkError(let urlError):
action = .displayError
case .systemError(let sysError):
action = .displayError
case .userCancelled:
action = .noAction
case .notAvailableInStorefront:
action = .displayError
case .notEntitled:
action = .displayError
case .unknown:
action = .displayError
default:
action = .displayError // <--- here, todo
}
}
}
return action
}
}