带有已发布变量的 SwiftUI Singleton ObservableObject 在首次显示时未更新

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

我有一个基本的 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()
}

第一次显示此屏幕时,没有显示任何产品。然而,第二次以及此后的每一次,产品都显示良好。 为什么它们第一次不显示?我该如何修复?

swift swiftui in-app-purchase storekit observableobject
1个回答
0
投票

您从

.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
}
© www.soinside.com 2019 - 2024. All rights reserved.