3

I have a problem with NSFetchedResultController. I have a button that saves two values to Core Data: actualDate and shortDate. The actualDate is an NSDate variable (eg. 2014-12-04 08:35:59 +0000) and the shortDate is a String, created from actualDate via NSDateFormatter (eg. 04 dec).

Below this button is a tableView that should display all entries, sorted by date in descending order with shortDate as the section name for each day(eg. 04 dec). This works fine with my current code WHILE RUNNING the app.

The problem appears when I close the app and start it again. The entries are still in the right order, but the section names is rearranged so that, for instance, 30 november is displayed before 4 december. I really don't know what the problem is or how to solve it.

Any help is appreciated!

Here's my code for NSFetchedResultController:

// MARK: - Fetched results controller

var fetchedResultsController: NSFetchedResultsController {
    if _fetchedResultsController != nil {

        return _fetchedResultsController!
    }

    let fetchRequest = NSFetchRequest()
    // Edit the entity name as appropriate.
    let entity = NSEntityDescription.entityForName("List", inManagedObjectContext: self.managedObjectContext!)
    fetchRequest.entity = entity

    // Set the batch size to a suitable number.
    fetchRequest.fetchBatchSize = 20

    // Edit the sort key as appropriate.
    let sortDescriptor = NSSortDescriptor(key: "actualDate", ascending: false)
    let sortDescriptor2 = NSSortDescriptor(key: "shortDate", ascending: false)

    fetchRequest.sortDescriptors = [sortDescriptor, sortDescriptor2]


    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!, sectionNameKeyPath: "shortDate", cacheName: nil)
    aFetchedResultsController.delegate = self
    _fetchedResultsController = aFetchedResultsController

    var error: NSError? = nil
    if !_fetchedResultsController!.performFetch(&error) {
        // Replace this implementation with code to handle the error appropriately.
        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
        //println("Unresolved error \(error), \(error.userInfo)")
        abort()
    }

    return _fetchedResultsController!
}
var _fetchedResultsController: NSFetchedResultsController? = nil

func controllerWillChangeContent(controller: NSFetchedResultsController) {
    self.tableView.beginUpdates()
}

func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
    switch type {
    case .Insert:
        self.tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
    case .Delete:
        self.tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
    default:
        return
    }
}

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
    switch type {
    case .Insert:
        tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
    case .Delete:
        tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
 /*   case .Update:
        self.configureCell(tableView.cellForRowAtIndexPath(indexPath!)!, atIndexPath: indexPath!)*/
    case .Move:
        tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
        tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
    default:
        return
    }
}

func controllerDidChangeContent(controller: NSFetchedResultsController) {
    self.tableView.endUpdates()
}
maxpetter
  • 263
  • 1
  • 2
  • 6
  • How are your dates stored in Core Data? – Garret May 05 '15 at 23:00
  • Have you tried this? http://stackoverflow.com/questions/4418703/a-nsfetchedresultscontroller-with-date-as-sectionnamekeypath – Garret May 05 '15 at 23:01
  • Was there a solution to this issue? The link above suggest way to sectionKey by date objects, but do not touch on the issue asked that section headers are now displayed out of order when the app is resumed. – InitJason Feb 05 '16 at 11:59

1 Answers1

0

I know this is a old question but I faced the same problem and somehow I managed to solve this by setting a cacheName instead of letting it nil.

I answered this old question for everyone facing the same problem.

AndreiVataselu
  • 216
  • 2
  • 16