SwiftUI:列表中的数据有时出现有时不出现

SwiftUI: Data in list appears sometimes and sometimes not

我有问题。在我的应用程序中,我有带有设备的 CoreData 和设备的 IP。我想发出 API 请求以从选定设备获取 JSON 数据并将它们显示在列表中。我的问题是它有时有效,有时无效,并且当我更改数据时列表不会更新。我希望有人能帮助我。

BouquetAPIModel.swift

struct BouquetAPIModel: Codable {
    let success: String
    let data: DataClass
}

// MARK: - DataClass
struct DataClass: Codable {
    let bouquets: [Bouquet]
}

// MARK: - Bouquet
struct Bouquet: Codable {
    var number, name: String
}

Device.swift

public class Device: NSManagedObject, Identifiable {
    @Published var bouquets : [Bouquet] = [Bouquet]()

    func fetchBouquetList() {
        fetchAPIRequest(apiPath: "/control/getbouquets?format=json") { (res: Result<BouquetAPIModel, Error>) in
            switch res {
            case .success(let bouquets):
                self.bouquets = bouquets.data.bouquets
            case .failure(let err):
                print("Fail to fetch bouquets: ", err)
            }
        }
    }


    fileprivate func fetchAPIRequest<T: Decodable>(apiPath: String, completion: @escaping (Result<T, Error>) -> ()) {
        let urlString = getApiUrl(apiPath: apiPath)
        guard let url = URL(string: urlString) else { return }

        URLSession.shared.dataTask(with: url) { (data,resp, err) in

            if let err = err {
                completion(.failure(err))
                return
            }

            do {
                let welcome = try JSONDecoder().decode(T.self, from: data!)
                completion(.success(welcome))
            } catch let jsonError {
                completion(.failure(jsonError))
            }

        }.resume()    
    }

BouquetView.swift

import SwiftUI

struct BouquetView: View {
    @Binding  var device : Device?
    @State var bouquets: [Bouquet] = [Bouquet]()

    var body: some View {
        VStack {
            Text(String(device?.deviceName ?? "fehler")).onTapGesture {
                self.device?.bouquets.removeFirst()
                print("Touch")
            }
            List (self.bouquets, id: \Bouquet.name) { bouquet in
                VStack(alignment: .leading) {
                    Text(bouquet.name)
                }
            }
        }.onAppear(perform: loadBouquets)
    }

    func loadBouquets() {
        if device == nil {
            //TODO jumo to settings
        }
        else {
            device?.fetchBouquetList()
            self.bouquets = device!.bouquets
        }
    }
}

struct BouquetView_Previews: PreviewProvider {
    static var previews: some View {
        BouquetView(device: .constant(nil))
    }
}

你能像下面这样更新你的设备吗?

public class Device: ObservableObject, Identifiable {
...
}

并确保在传递给 BouquetView

之前使用注释 @ObservedObject 声明您的设备

抓取时间可能会很长,所以您已经开始竞速了。为避免这种情况,可以使用以下方法

1) 删除以下行,因为此时数据可能尚未准备好

self.bouquets = device!.bouquets

2) 为数据集添加显式监听器

if device == nil {
    //TODO jumo to settings
    device!.$bouquets
       .assign(to: \.bouquets, on: self)
       .store(in: &cancellables) // << you will need to create this store var
}