Integrating FetchRequest with List(:id:children:)

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!

  1. 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 of topLevelCategories -- is this correct?
  2. Is there any way to return a FetchedResults<Category>? from a non-UI class, or otherwise combine @FetchRequest with the nested List introduced in iOS 14?
  3. If not, what is the "SwiftUIy" way of doing this task? Should I be "unrolling" the list manually by explicitly calling OutlineGroup in the ForEach? Should I be duplicating my Core Data contents into a @Published property on a shared singleton and running all writes through that property? Or something else altogether?

Note: the code I pasted above contains an error:

@FetchRequest(entity: Task.entity(), sortDescriptors: [NSSortDescriptor(key: "name", ascending: true)], predicate: NSPredicate(format:"parent == nil"))

should be

@FetchRequest(sortDescriptors: [NSSortDescriptor(key: "name", ascending: true)], predicate: NSPredicate(format:"parent == nil"))

The compiler error I quoted above comes from the latter. Blame the former on too much twiddling to see if different @FetchRequest patterns behave differently…

Integrating FetchRequest with List(:id:children:)
 
 
Q