UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

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 :)

1      

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.

1      

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

1      

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.

1      

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.

1      

TAKE YOUR SKILLS TO THE NEXT LEVEL If you like Hacking with Swift, you'll love Hacking with Swift+ – it's my premium service where you can learn advanced Swift and SwiftUI, functional programming, algorithms, and more. Plus it comes with stacks of benefits, including monthly live streams, downloadable projects, a 20% discount on all books, and free gifts!

Find out more

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

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

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.