Search code examples
iosswiftnsfetchedresultscontroller

Format sectionNameKeyPath NSFetchedResultsController - Swift


I am attempting to format my sectionNameKeyPath for my core data fetch using a stored NSDate attribute. It is fully working and pulling/sorting the records into sections based on the NSDate but I am not sure how to format it to display it by dd-mm-yyyy.

I know how to format NSDate using:

let date = NSDate(timeIntervalSince1970:myTimeInterval)
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy"

My current fetch request using core data attribute sectionDate as the section division for sectionNameKeyPath

FETCH

let fetchRequest = NSFetchRequest(entityName: "VisitDetails")
let primarySortDescriptor = NSSortDescriptor(key: "dateDue", ascending: false)
let sortDescriptors = [primarySortDescriptor]
fetchRequest.sortDescriptors = sortDescriptors
        
let frc = NSFetchedResultsController(
            fetchRequest: fetchRequest,
            managedObjectContext: self.managedObjectContext!,
            sectionNameKeyPath: "dateSections",
            cacheName: nil)
        
frc.delegate = self

So to clarify I am wanting to format the output and sort by just the dd-MM-yyy. Currently, it is looking like:

enter image description here

I presume a Hack is creating an additional attribute and inputting a formatted string then using this to section the results?


Solution

  • I just did just this for a project that I'm working on. Here's what I did:

    Optional, but highly recommended, is to set up mogenerator. There is a nice tutorial here for setting up your core data project to use it.

    Regardless, in your data model, make sure you have a NSManagedObject subclass associated with the entity. If you haven't already, and you're not using mogenerator, then you can do it the apple way.

    In your VisitDetails class, add:

    var formattedDateDue: String {
        get {
            let dateFormatter = NSDateFormatter()
            // Apple suggested locale-aware technique:
            // dateFormatter.dateStyle = .ShortStyle
            // dateFormatter.timeStyle = .NoStyle
            // ..or to stick to your original question:
            dateFormatter.dateFormat = "dd-MM-yyyy"
            return dateFormatter.stringFromDate(self.dateDue)
        }
    }
    

    (Assuming you want your sections to be grouped on dateDue's date, otherwise make the computed attribute for your dateSections attribute.) You then modify your fetched results controller from above to use the computed attribute:

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

    And that's all there is to it!