6

NSOrderedSets save the order of the objects in the table. If you access an NSManagedObject subclass instance with a property that is an NSOrderedSet, then they will be in order.

However, there is seemingly no way to access that order using an NSSortDescriptor when creating an NSFetchRequest.

It appears from the raw SQLite DB, that order is stored in fields named Z_FOK_<relationship name>. The data is available, but it doesn't appear to be visible through the core data APIs.

Does anyone know a way to write an NSSortDescriptor that will work with a SQLite DB to return the results in the order specified by the NSOrderedSet?


Update

Related Question: NSFetchedResultsController and NSOrderedSet relationships

Community
  • 1
  • 1
Corey Floyd
  • 25,929
  • 31
  • 126
  • 154

2 Answers2

3

I don't think that is possible. The "ordering" is associated with the to-many relationship from one entity A to another entity B, it is not a property of the target entity B. But a sort descriptor for a Core Data fetch request can only use (persistent) properties of the entity.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • 1
    That seems to be what I see too… I just couldn't believe that there isn't some special support for this in NSSortDescriptor so that NSFetchedResultsControllers can take advantage of the order. Otherwise, developers still need to add and manually manage a "sortOrder" property - which kinda defats the purpose of the NSOrderedSet. – Corey Floyd Jul 29 '13 at 19:21
  • @CoreyFloyd: Note that you can have two ordered relationships `A1 <-->> B` and `A2 <-->> B` with completely different orderings of the `B` objects, so "fetching B objects sorted according to the ordered relationship" would be ambiguous anyway. – Martin R Jul 29 '13 at 19:22
  • NSFetchRequest has to be created with a sort descriptor. But if there was some way to create it without a sort descriptor (Using a category, subclass, etc...) maybe when you executed the fetch request it would default to the NSOrderedSet order. Most likely it would just be undefined behavior but it might be worth a shot. – Dylan Kirkby Jul 29 '13 at 19:39
  • @DylanKirkby: The entity does not have a "NSOrderedSet order" that could be used by default. The ordering is a feature of the relationship between two entities. – Martin R Jul 29 '13 at 19:49
-1

I've tried this in swift just now and it seemed to work for me.

var sectionsExcludingEmpty: [SurveyAnswerSection] {
    let fetchRequest: NSFetchRequest<SurveyAnswerSection> = NSFetchRequest.init(entityName: "SurveyAnswerSection")
    fetchRequest.predicate = NSPredicate.init(format: "surveyAnswer == %@ AND hidden == FALSE", self)
    fetchRequest.sortDescriptors = [ NSSortDescriptor(key: "surveyAnswer", ascending: true) ]
    if let moc = self.managedObjectContext {
        do {
            let results = try moc.fetch(fetchRequest)
            return results
        } catch {
            fatalError("Could not get sectionsExcludingEmpty: \(error)")
        }
    } else {
        fatalError("Unable to get own managed object context")
    }
}

When I missed off the line fetchRequest.sortDescriptors = [ NSSortDescriptor(key: "surveyAnswer", ascending: true) ] it ordered seemingly randomly, but with the line added it sorted as expected.

In my case SurveyAnswerSection has a one to ordered-many relationship with SurveyAnswer.

robwithhair
  • 350
  • 3
  • 11