WWDC22 SALE: Save 50% on all my Swift books and bundles! >>

Grouping fetched Core Data by section

Forums > SwiftUI

Greetings,

I've searched a lot but so far, I haven't found a way to make it work, to the point where I'm wondering if it's even possible.

I use Core Data and fetch the content using this:

@FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Host.hostName, ascending: true)],
        animation: .default)
    private var hosts: FetchedResults<Host>

This is the content of my Entity: https://ibb.co/b1LwtRs

It works well and get me the full list of records, however it does it in the traditional way, a flat list, that looks like that today: https://ibb.co/TrSWTgV

What I would like to do is group them by section, using the Attribute "hostEnvironment" (which either has a value provided by the user when adding a new host, or defaults to "N/A" if left empty), so it looks like that: https://ibb.co/72w5Dsb

All the references and examples I find online are making section based on the date of the record, and no matter what I try to adapt it, Xcode always finds a way to complain. I've also tried the new @SectionFetchRequest, but when adding to the ForEach part of the code, I also got errors.

So back to my initial question: is what I would like to achieve possible?

Thank you :)

   

Yes, it is possible.

Without seeing how you contain your NSFetchRequest, I can't give specific pointers. However in principle you would use a combination of an array and a set to manipulate which are your groups, and DisclosureGroup to wrap around your ForEach list items. Also a new function.

The array would contain the strings of the atrributes in your case hostAtrributes. The set would be a copy of that array, but since it is a set any duplicates are removed. The function would provide an array, dynamically, to the ForEach loop for the grouping in the DisclosureGroup, but only if the array is not empty. Finally remembering to have an update function that will update the array if the values of hostAttributes changes, so creating an updated array and set.

   

Thank you for your answer Greenamberred. If you want, you can have a look at the entire code here: https://www.hackingwithswift.com/forums/swiftui/working-with-queue-and-unexpected-i-do-not-expect-it-behavior/13431

   

var groupedHosts = [String]()

func updateGroupedHostsList() {
    var groupedHostsList = Set<String>()
    for host in hosts where host.hostEnvironment != nil {
        groupedHostList.insert(host.hostEnvironment!)
    }
    groupedHosts = groupedHostsList.sorted()
}

func hostForGroup(_ hosts: [Host], _ group: String) -> [Host] {
    guard !hosts.isEmpty else { return [] }    // there are some entities to process, otherwise return an empty array
    var groupedHostList = [Host]()
    for host in (hosts.filter { $0.hostEnvironment == group } ) {
        groupedHostList.insert(host, at: 0)
    }

    return groupedHostList
}

var body: some View {
     NavigationView {
         List {
            ForEach(groupedHosts, id: \.self) { group in
                let groupList = hostForGroup(hosts, group)
                if !groupList.isEmpty {      // not an empty list
                    DisclosureGroup(group) {
                        ForEach(hosts) { host in
                             NavigationLink(destination: DetailedHostView(host: host)) {

…  // several closing } will be needed here

func getCoreDataRecordCount() -> Int{
…     
        updateGroupedHostsList()

        return countOfItems
    } // end func

Hopefully this will help you , or give you some further ideas.

A couple of things I would add, would be to look into separating your data processing / manipulation from your view (i.e. follow the MVVM approach where possible), and refactoring your code in to more manageable pieces.

   

Thank you for your detailed answer! Seems overly complicated to my newbie status of coding with SwiftUI. I guess I will park this item until I have a better understanding of what I'm actually doing here.

   

Hacking with Swift is sponsored by Fernando Olivares

SPONSORED Fernando's book will guide you in fixing bugs in three real, open-source, downloadable apps from the App Store. Learn applied programming fundamentals by refactoring real code from published apps. Hacking with Swift readers get a $10 discount!

Read the book

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.