@Published变量在API调用后不会重新加载我的视图吗?

时间:2020-09-01 03:25:10

标签: swift swiftui

我相信我已经正确设置了我的视图和视图模型。我还确认了网络请求(通过控制台)返回了数据。我对为什么我发布的媒体资源不使用获取的数据更新视图感到困惑。

这是我的视图模型:

 class ProductViewModel: ObservableObject {
    var didChange = PassthroughSubject<ProductViewModel, Never>()
    @Published var mensProducts = [StripeProduct]()
    
    init() {
    }
    
    func getMenItems() {
        // hit the URL and
        guard let url = URL(string: "http://127.0.0.1:3000/bags") else {
            return
        }
        
        URLSession.shared.dataTask(with: url) { (data, response, err) in
            // return the data asynchronously so that the call doesn't have to complete before loading the UI
            DispatchQueue.main.async {
                print("Decode data")
                self.mensProducts = try! JSONDecoder().decode([StripeProduct].self, from: data!)
            }
        }
        .resume()
    }
}

这是我的观点:

struct MenProducts: View {
    @ObservedObject var productVM = ProductViewModel()
    var body: some View {
        GeometryReader { geometry in
            ScrollView {
                VStack {
                    ForEach(self.productVM.mensProducts) { item in
                        ProductView(productID: item.productID, photo: "menMerch", price: item.price, name: item.productName, height: geometry.size.height/2, width: geometry.size.width)
                    }
                }
            }
        }
        .onAppear(perform: self.productVM.getMenItems)
    }
}

1 个答案:

答案 0 :(得分:1)

首先,我建议您将getMenItems()调用移至init()的{​​{1}}方法。

然后,您可以在ProductViewModel视图中删除.onAppear(perform: self.productVM.getMenItems)并在MenProducts中标记方法private,因为没有外部类/结构会调用它。 / p>

我还建议您不要使用ProductViewModel显式调用后台队列,因为DispatchQueue.main.async数据任务操作已经是异步的。

您可以在这篇很棒的文章中了解有关对模型进行JSON解码的更多信息:https://www.avanderlee.com/swift/json-parsing-decoding/