I have this class which calls an API every 3 seconds (using a timer) and saves the result in the @Published array named items:
public class ApiAdapter: ObservableObject {
@Published var items = [Item]()
init() {
api = Api(...)
Timer.scheduledTimer(withTimeInterval: 3, repeats: true) { timer in
api.getItems() { items in
if let _items = items {
self.items = _items
}
}
}
}
}
The ApiAdapter is used throughout the entire app so I decided to make it an @EnvironmentObject.
In the main view of my app I'm accessing the apiAdapter.items array for displaying it in a list like so:
struct MainListView: View {
@EnvironmentObject var apiAdapter: ApiAdapter
var body: some View {
NavigationView {
List {
ForEach(apiAdapter.items, id: \.hash) { i in
Text(i.name)
...
}
}
.navigationBarItems(trailing:
Menu {
Picker(selection: $category, label: Text("Filter")) {
Text("Category 1").tag(1)
Text("Category 2").tag(2)
Text("Category 3").tag(3)
}
} label: {
Image(systemName: "line.horizontal.3.decrease.circle")
.imageScale(.large)
}
}
}
}
In MainListView I have also some Menus in the navigationBar which get closed every time the apiAdapter updates the items variable, so it makes it hard to use them.
How is it possible to update only the list and not the entire view? or even better how is it possible to update only the items that changed in the last api call?