Thanks for the thread. As a newcomer to SwiftUI, though, I'm not sure how this would actually map in practice. For example, if I had a setup like this:
struct FileItem {
var name: String
var size: Int64
static var all: [FileItem] = { ... }
static var favourites: [FileItem] = { ... }
func setAsFavourite(isFavourite: Bool) { ... }
}
It's the part that goes in those "..." that I'm having some trouble figuring out. I have experience with Android and I know how I'd go about it there: I'd have a Repository which queries the file system (and potentially caches the latest data), a view model which holds view-specific state (for example, maybe just the file items in a specific folder) and handles any sorting, filtering etc..., and a view which asks the view model to refresh the data on certain events, such as onResume. If async is needed, I'd just launch that in a viewModelScope inside the view model.
I'm not sure how to map this to SwiftUI with the model described in this post.
For example, if I did:
struct MyApp: App {
@State var allItems = FileItem.all
@State var favouriteItems = FileItem.favourites
var body: some Scene {
WindowGroup {
NavigationView {
MyListView(allItems)
MyListView(favouriteItems)
}
}
}
}
struct MyListView {
@Binding var items: [FileItem]
// Imagine there's a list here with buttons, and I can toggle the favourite status by tapping on the button for that item.
So what exactly should be happening if I call FileItem.setAsFavourite? Should it be adding a copy of the struct to the favourites array?
Would it make more sense to have things like "isFavourite" be instance vars, and then a collection like "favourites" would be a computed property? If so, would favourites still be a @State or otherwise how would the second list know that the value of the computed property changed? Would @State var favouriteItems = FileItem.favourites still work in that case?
How could collection updates be propagated? Would that look something like this:
async func syncCollectionWithFs() {
// ... query FS
var collection = query()
MainActor.run {
FileItem.all = collection
FileItem.favourites =// Assume I'd map against some favourites DB to see what was marked as a favourite.
}
}
But then how does this actually get propagated to the @States? By assigning the contents as a @State, didn't I already make a copy and updating the struct static vars isn't necessarily going to be published? Is this where ObservableObject would make more sense? I'm curious what the use case of the static funcs & vars on the structs are and how they are intended to be used.
How would this change if we make the collections async sequences or the functions async?
I think I'd know how I'd solve these questions if I was doing something more similar to Android with ViewModels and ObservableObjects, so these might seem like really basic questions, but as I said I'm coming from another universe, and I'm curious. ;) Thank you.
Topic:
UI Frameworks
SubTopic:
SwiftUI
Tags: