0

I have an iOS app that uses core data and CloudKit. The data model is simple and it contains a date and a string element that stores the date formatted as EEEE, MMM d yyyy.

When I run a SectionedFetchRequest and display the results in a list, after I have more than two sections the sort order all the sudden "jumps" and mixes the entries under each section. If I delete the app and reinstall it, the data that comes from iCloud is correctly formatted, but when I close the app and reopen it, again the sort order gets all mixed up. This happens with three or more sections and the order mix-up is not always the same (at least that I can observe).

Here's what I mean:

Two sections

enter image description here

Adding another entry, creating a third section

enter image description here

Closing the app and reopening, order gets mixed up

enter image description here

I have tried to look at how the data gets sorted via FetchedResults and SectionedFetchResults, I have tried to change how the list is created, and I have gone through the debug messages from CloudKit, but I can't figure out what's going on.

This is the data model:

enter image description here

And the code to fetch the data and display it on the list:

@Environment(\.managedObjectContext) private var viewContext
    
@FetchRequest(entity: Item.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Item.date, ascending: false)])
var entries: FetchedResults<Item>

@SectionedFetchRequest<String, Item>(
    sectionIdentifier: \.dateText!,
    sortDescriptors: [SortDescriptor(\.date, order: .reverse)]
)
var sections: SectionedFetchResults<String, Item>


NavigationView {
    List {
        ForEach(sections) { section in
             Section(header: Text(section.id)) {
                ForEach(section) { entry in
                    Text(entry.text!)
                }
             }
        }
    }
}

At this point I'm out of ideas of what else can it be. Since it's coming from iCloud formatted correctly, I'm assuming the issue is during the fetch requests and the sorting happening there, but I don't know enough to understand whether I'm doing something wrong in how I fetch the data, or whether there is another bug. Any help is appreciated.

Aleph
  • 465
  • 2
  • 12
  • 2
    The documentation for `SectionedFetchRequest` states _"Be sure that you choose sorting and sectioning that work together to avoid discontiguous sections"_ and this is what I think is the issue, the sort order for `dateText` and `date` are completely different. I would look into using a date formatter instead and only working with the `date` property for this. There seems to be multiple similar questions here on SO for using a Date attributer as a section identifier to look at. – Joakim Danielson Jan 06 '23 at 09:04
  • 1
    Also using only the `date` attribute would mean you don't need a duplicate string attribute which can always be problematic. – Joakim Danielson Jan 06 '23 at 09:07
  • @JoakimDanielson Thank you Joakim. Let me check.... – Aleph Jan 06 '23 at 12:47
  • @JoakimDanielson `sectionIdentifier` takes a string. I'm trying to pass a formatted `\.date`, but it can't find `.date`. Trying to pass `Item.date` but also, a collection errors. How would you suggest that I SectionedFetchRequest with a formatted `sectionIdentifier` by date? – Aleph Jan 06 '23 at 13:28
  • I tried things like the ones in this article and same issue with the error: https://stackoverflow.com/questions/59180698/how-to-properly-group-a-list-fetched-from-coredata-by-date – Aleph Jan 06 '23 at 13:32
  • Same with other articles that force me to add huge chunks of additions `extension` code to sort by date...????? – Aleph Jan 06 '23 at 13:36
  • I'm going to give this a try, but I don't know if it will work on CloudKit https://www.hackingwithswift.com/forums/swiftui/show-dates-saved-in-coredata-by-year-sections/6382 – Aleph Jan 06 '23 at 13:40

1 Answers1

0

Section order has to match sort order, the weekdays are being sorted in alphabetical order which is a different order from the dates. Try yyyy-MM-dd for the dateText. Then you will need to format it again for displaying the section text and usually that would be localised.

malhal
  • 26,330
  • 7
  • 115
  • 133