在 swiftUI 中定期更新列表

Periodically update list in swiftUI

我正在尝试构建一个从服务器加载列表并每 x 秒更新每个列表项视图的 macOS 应用程序。

我浏览了一些现有代码并遵循了一些教程,因为我仍在学习,但我似乎无法弄清楚出了什么问题。

我有一个 Store 保存数据并像这样定期更新它:

class Store: NSObject, ObservableObject {
    @Published var items: [Item]
    var timer: Timer = Timer()

    override init() {
        var newItems: [Item] = []
        // updateList calls the web service and receives a `[Item]`
        updateList(update: { i in
            newItems = i
        })
        items = newItems
    
        super.init()
    
        startTimer()
    }

    func startTimer() {
        self.timer = Timer.scheduledTimer(withTimeInterval: 5, repeats: true, block: { _ in
            var newList: [Item] = []
            updateList(update: { vals in
                newList = vals
            })
            self.objectWillChange.send()
            items = newList
        })
    }
}

视图如下所示:

struct ContentView: View {
    @ObservedObject var store: Store

    var body: some View {
        VStack(alignment: .leading, spacing: 12) {
            List(store.items, id: \.self) { item in
                ListRow(item: binding(for: item))
            }
        }
        .frame(minWidth: windowSize().minWidth, minHeight: windowSize().minHeight)
        .navigationTitle("Mission")
        .toolbar {
            ToolbarItem(placement: .status) {
                Button(action: { /* Show connect dialog */ }) {
                    Image(systemName: "network")
                }
            }
            ToolbarItem(placement: .primaryAction) {
                Button(action: { /* Show file chooser/magnet entry dialog */ }) {
                    Image(systemName: "plus")
                }
            }
        }
    }

    func binding(for item: Item) -> Binding<Item> {
        guard let index = store.items.firstIndex(where: { [=11=].id == item.id }) else {
            fatalError("Can't find in array")
        }
        return $store.items[index]
    }
}

struct ListRow: View {
    @Binding var item: Item
    var body: some View {
        Text(item.name)
            .padding(.all, 20)
    }
}

当我 运行 应用程序时,它是一个空列表。我可以添加断点,我可以看到项目列表正在正确发送,所以我觉得列表视图本身做错了什么,但我不确定。我唯一确定的是我的 updateList 方法 100% 返回 Item 的列表。有什么想法吗?

尽管您没有显示足够的代码来重现您的问题,尤其是 updateList 所做的,请尝试这样的事情(未经测试的代码):

class Store: NSObject, ObservableObject {
    @Published var items: [Item] = [] // <-- here
    var timer: Timer = Timer()

    override init() {
        super.init()
        // updateList calls the web service and receives a `[Item]`
        updateList(update: { vals in // <-- here
            self.items = vals       // <-- here
        })
        startTimer()
    }

    func startTimer() {
        self.timer = Timer.scheduledTimer(withTimeInterval: 5, repeats: true, block: { _ in
            self.updateList(update: { vals in   // <-- here
                self.objectWillChange.send()    // <-- here
                self.items = vals               // <-- here
            })
        })
    }

}

你还必须在 ContentView 之前有类似的东西, @StateObject var store = Store() 你传递为 ContentView(store: store).