Search code examples
iosswiftuitableviewcore-datansfetchedresultscontroller

Getting undesired number of sections from fetchedResultsController


I'm having an issue getting a tableView to update properly, though I've made some progress. I think the source if my trouble lies in my fetchedResultsController returning an undesired number of sections.

My objective is to have the SongSequences displayed in one section sorted by songSequenceTitle. What I've done with my fetchedResultsController ends up treating each SongSequence as a new section.

I have Songs that are added to a SongSequence as an NSOrderedSet. Here's what my NSManagedObjects look like:

extension SongSequence {

    @NSManaged var songSequenceTitle: String!
    @NSManaged var songs: NSOrderedSet!

}

extension Song {

    @NSManaged var favorite: NSNumber!
    @NSManaged var songDescription: String!
    @NSManaged var songFilename: String!
    @NSManaged var songStar: String?
    @NSManaged var songSequences: NSOrderedSet!

}

When I pull them out of the managedObjectContext, my fetchedResultsController is seeing each SongSequence as a separate section, which is wreaking havoc on my NSFetchedResultsController delegate methods and tableView update methods when the managedObjectContext changes.

lazy var fetchedResultsController: NSFetchedResultsController = {
    let fetchRequest = NSFetchRequest(entityName: "SongSequence")
    let sortDescriptor = NSSortDescriptor(key: "songSequenceTitle", ascending: true);
    fetchRequest.sortDescriptors = [sortDescriptor]

    let frc = NSFetchedResultsController (fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext, sectionNameKeyPath: "songSequenceTitle", cacheName: nil)

    frc.delegate = self

    return frc
}()

I'm stumped as to why the fetchedResultsController is seeing each SongSequence as a separate section.

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    print("PlaylistVC numberOfSectionsInTableView = \(fetchedResultsController.sections!.count)")
    // This is equal to the number of SongSequences in my MOC
    return fetchedResultsController.sections!.count
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // This is always 1
    let numberOfRowsInSection = fetchedResultsController.sections?[section].numberOfObjects
    return numberOfRowsInSection!
}

How can I display all the SongSequences in a single section?


Solution

  • In your fetched results controller, you specified a non-nil sectionNameKeyPath. This is grouping song sequences by title, and since each song sequence title is distinct, each one appears in its own section.

    A key path on result objects that returns the section name. Pass nil to indicate that the controller should generate a single section.

    Initialize your frc by setting the sectionNameKeyPath to nil, to avoid grouping the song sequences by section.

    let frc = NSFetchedResultsController (fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)