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

Posted

技术标签:

【中文标题】SwiftUI:列表中的数据有时出现有时不出现【英文标题】:SwiftUI: Data in list appears sometimes and sometimes not 【发布时间】:2020-01-02 18:40:30 【问题描述】:

我有问题。在我的应用程序中,我有带有设备的 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))
    


【问题讨论】:

【参考方案1】:

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

public class Device: ObservableObject, Identifiable 
...

并确保在传递给BouquetView之前使用注释@ObservedObject声明您的设备

【讨论】:

带来错误:“设备”与协议“ObservableObject”的冗余一致性 请尝试新的更新,ObserverableObject 符合类型NSManagedObject 所以摆脱NSManagedObject 然后我在另一个视图中得到类型“设备”不符合协议“NSFetchRequestResult”,我使用 Fetchrequest 获取核心数据 处理核心数据是不同的场景。您可以尝试使用这种情况来确保从服务器加载数据并在您的视图中更新。 您可以创建一个新类来处理从服务器获取数据。【参考方案2】:

获取可能会很长,所以您已经开始参加比赛了。为避免这种情况,可以使用以下方法

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

【讨论】:

在 if 或 else 中? if 中,因为loadBouquets 可以像我假设的那样被多次调用,但订阅者只能被分配一次。 但设备永远不会为零 这是你的代码……它是可选的。如果它从不为零,那为什么它是可选的?如果不是,那么您可以将订阅者分配放入init,类似于here 如果在另一个视图中没有选择潜水,它可能为零,但我选择了一个。我尝试使用 init

以上是关于SwiftUI:列表中的数据有时出现有时不出现的主要内容,如果未能解决你的问题,请参考以下文章

初学jsf,页面中列表数据使用<rich:datatable>,为啥横向滚动条有时候出现,有时候出不来呢。

SwiftUI 列表中某些行的布局问题

swiftui列表没有出现但数组不为空

如何为 SwiftUI 列表中的各个行设置动画?

BeautifulSoup 有时会出现异常

SwiftUI 嵌套列表不出现