我有一个基本的 IAP 商店,如下所示:
import StoreKit
class Store: ObservableObject {
static let shared = Store()
private var productIDs = ["test.credits", "test.lifetime"] //consumable, non-consumable
@Published var products = [Product]()
private init() {
Task {
await requestProducts()
}
}
@MainActor
func requestProducts() async {
do {
products = try await Product.products(for: productIDs)
} catch {
print(error)
}
}
}
在一个视图中,我正在尝试展示这样的产品:
VStack {
ForEach(Store.shared.products, id: \.id) { product in
Button(action: {
Task {
try await Store.shared.purchase(product)
}
}, label: {
HStack {
Text(product.displayName)
Spacer()
Text("\(product.displayPrice)")
}
})
}
}
.task {
await Store.shared.requestProducts()
}
第一次显示此屏幕时,没有显示任何产品。然而,第二次以及此后的每一次,产品都显示良好。 为什么它们第一次不显示?我该如何修复?
您从
.task
调用的异步函数应该返回您传递给商店的结果,例如像这样的:
@EnvironmentObject var store: Store
@Environment(\.service) var Service
...
.task {
store.products = await service.fetchProducts()
}
struct ProductService {
func fetchProducts() async -> [Product] { // usually this throws
// do your network request
}
}
对于按钮任务,如下所示:
Button(isPurchasing : "Cancel" : "Purchase") {
isPurchasing.toggle()
}
.task(id: isPurchasing) {
if !isPurchasing { return }
// complete the purchase
isPurchasing = false
}