My app has a hierarchy of categories -- that is, each Category can be contained in another Category (or not) and can contain [0…n] children. These categories are stored in Core Data; for easier use in SwiftUI, I've wrapped the children: NSSet? from Core Data with a readonly property called childCategories that returns a [Category]?.
I'd like to display these categories in a nested list. Calling a utility method which returns a [Category] allows me to use List(:id:children:) as expected; however, the resulting List does not update when a Category is edited because it's the result of a method call, and not an @Observable or @Published property.
So I switched to using a FetchRequest like so:
@FetchRequest(entity: Task.entity(), sortDescriptors: [NSSortDescriptor(key: "name", ascending: true)], predicate: NSPredicate(format:"parent == nil"))
private var topLevelCategories: FetchedResults<Category>
var body: some View {
List(topLevelCategories, id: \.self, children: \.childCategories) { category in
...
However, the call to List now yields a compiler error:
List(topLevelCategories, id: \.self, children: \.childCategories) { category in
^^^^^ Key path value type '[Category]?' cannot be converted to contextual type 'FetchedResults<Category>?'
Help!
- What is this error actually saying? My read is that it now expects the .childCategories to be of type
FetchedResults<Category>?as well, since this is the type oftopLevelCategories-- is this correct? - Is there any way to return a
FetchedResults<Category>?from a non-UI class, or otherwise combine@FetchRequestwith the nested List introduced in iOS 14? - If not, what is the "SwiftUIy" way of doing this task? Should I be "unrolling" the list manually by explicitly calling
OutlineGroupin the ForEach? Should I be duplicating my Core Data contents into a@Publishedproperty on a shared singleton and running all writes through that property? Or something else altogether?