SectionedFetchRequest mixes up the sections

I am presenting a list of Items which are sections by the categoryIdentifier property. My app uses CloudKit. When I add change the categoryIdentifier for an item it is display in the correct section and other running instances of the app do the same. When restarting the app some items are grouped under an incorrect section, but the cstegoryIdentifier within the item is still as it was set. My question is what I'm doing wrong that upon restart the organization is incorrect. In case it matters, I'm setting this in the container:         container.viewContext.automaticallyMergesChangesFromParent = true

As an aside: It seems necessary to make the sectioning type optional (as is the case in the underlying entity) like this SectionedFetchResults<String?, Item> Though the examples don't seem to need this.

struct ContentView: View {

    @Environment(\.managedObjectContext) private var viewContext

    @State private var isShowingItem = false

    @State private var isAddingItem = false

    

    @SectionedFetchRequest(

        sectionIdentifier: \.categoryIdentifier,

        sortDescriptors: [NSSortDescriptor(keyPath: \Item.name, ascending: true)],

        animation: .default) private var sectionedItems: SectionedFetchResults<String?, Item>

    

    var body: some View {

        NavigationView {

            List {

                ForEach(sectionedItems) { section in

                    Section(header: Text(Category.nameForId(section.id, context: viewContext)).font(.headline)) {

                        ForEach(section) { item in

                            NavigationLink(destination: ItemInputView(item: item, category: Category.get(identifier: item.category, context: viewContext))) {

                                Text(item.getName())

                            }

                        }

                    }

                }

            }

            

            .navigationTitle("Foo")

            .sheet(isPresented: $isAddingItem) {

                ItemInputView(item: nil, category: Category.getDefault(context: viewContext))

            }

        }

        .navigationViewStyle(.stack)

    }

}

Replies

I also faced the same problem with this code.

struct ContentView: View {
    @SectionedFetchRequest(
        sectionIdentifier: \Item.category!,
        sortDescriptors: [NSSortDescriptor(keyPath: \Item.name, ascending: true)],
        animation: .default)
    private var sections: SectionedFetchResults<String, Item>

    var body: some View {
        List {
            ForEach(sections) { section in
                Section(content: {
                    ForEach(section) { item in
                        Text(item.name!)
                    }
                }, header: {
                    Text(section.id)
                })
            }
        }
    }
}

↓ SOLUTION: add SortDescriptor

        sortDescriptors: [NSSortDescriptor(keyPath: \Item.category, ascending: true),
                          NSSortDescriptor(keyPath: \Item.name, ascending: true)],

I don't know why, but adding a SortDescriptor for the category to the beginning of the array worked fine.
I hope it helps.


ADD:

It is written in the document.

Be sure that you choose sorting and sectioning that work together to avoid discontiguous sections.

https://developer.apple.com/documentation/swiftui/sectionedfetchrequest