How to sort Core Data fetched properties

前端 未结 8 2028
太阳男子
太阳男子 2020-12-12 15:30

The Core Data Documentation states that:

The fetch request associated with the [fetched] property can have a sort ordering, and thus the fetched prope

相关标签:
8条回答
  • 2020-12-12 15:43

    For a single fetched property, Swift 4, Xcode 9.4:

    // retrieve the fetched property's fetch request    
    let fetchedPropertyRequest = (modelName.entitiesByName["entityName"]!.propertiesByName["fetchedPropertyName"] as! NSFetchedPropertyDescription).fetchRequest
    
    // set up the sort descriptors
    let sortDescriptors = [NSSortDescriptor(key: "keyName", ascending: true)]
    
    // add the sort descriptors to the fetch request
    fetchedPropertyRequest!.sortDescriptors = sortDescriptors
    

    Here's the same thing the loooonnnnnnggggggg way:

    // retrieve the fetched property's fetch request
    let theEntityDescription: NSEntityDescription = modelName.entitiesByName["entityName"]!
    let theFetchedPropertyDescription = theEntityDescription.propertiesByName["fetchedPropertyName"]! as! NSFetchedPropertyDescription
    let theFetchedPropertyRequest = theFetchedPropertyDescription.fetchRequest
    
    // set up the sort descriptors
    let sortDescriptor1 = NSSortDescriptor(key: "keyName", ascending: true)
    let theSortDescriptors = [sortDescriptor1]
    
    // add the sort descriptors to the fetch request
    theFetchedPropertyRequest!.sortDescriptors = theSortDescriptors
    

    Note: for this example, I force-unwrapped values. Make sure that you account for optional values in your actual code!

    0 讨论(0)
  • 2020-12-12 15:47

    The modeling tool doesn't appear to have a way to set the sort descriptors on the fetch request.

    It should be possible[1] to, after loading the model but before associating it with a persistent store coordinator, to find the fetched property descriptions for which you want to control the sort order, and replace their fetch requests with fetch requests that have sort descriptors set on them.

    [1] In principle this should work. In practice, I have not done so or tested it.

    0 讨论(0)
  • 2020-12-12 15:49

    Sadly, though, the ability to sort is somewhat limited. For example, you cannot take a field that is an NSString containing a number, and sort it numerically, at least not with a SQLite backing store. As long as you are sorting alphabetically on strings, numerically only on values stored as numbers and so forth, though, the NSSortDescriptor applied to the fetch request works just fine.

    0 讨论(0)
  • 2020-12-12 15:54

    You don't specify them in the graphical editor (as far as I know).

    You specify them in the code where you make the fetch.

    NSFetchRequest* request = [[NSFetchRequest alloc] init];
    NSEntityDescription* entity = [NSEntityDescription entityForName:@"whatYouAreLookingFor"
        inManagedObjectContext:self.managedObjectContext];
    [request setEntity:entity];
    
    // here's where you specify the sort
    NSSortDescriptor* sortDescriptor = [[NSSortDescriptor alloc]
                                    initWithKey:@"name" ascending:YES];
    NSArray* sortDescriptors = [[[NSArray alloc] initWithObjects: sortDescriptor, nil] autorelease];
    [request setSortDescriptors:sortDescriptors];
    [sortDescriptor release];
    
    fetchedResultsController = [[NSFetchedResultsController alloc]
                   initWithFetchRequest:request
                   managedObjectContext:self.managedObjectContext
                     sectionNameKeyPath:nil
                              cacheName:@"myCache"];
    
    0 讨论(0)
  • 2020-12-12 15:57

    You can actually grab the model fetched property and add the sort descriptors to it (again, in code). I did this in the standard method that XCode generates in your AppDelegate if you choose one of the templates with Core Data:

    By the way. This sorts ALL fetched properties on ALL models in your data model. You could get fancy and adaptive with it, but it was the most succinct way to handle sorting the 7 separate models that each had fetched properties that needed to be sorted by name. Works well.

    /**
     Returns the managed object model for the application.
     If the model doesn't already exist, it is created by merging all of the models found in the application bundle.
     */
    - (NSManagedObjectModel *)managedObjectModel {
    
        if (managedObjectModel != nil) {
            return managedObjectModel;
        }
        managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];    
    
        // Find the fetched properties, and make them sorted...
        for (NSEntityDescription *entity in [managedObjectModel entities]) {
            for (NSPropertyDescription *property in [entity properties]) {
                if ([property isKindOfClass:[NSFetchedPropertyDescription class]]) {
                    NSFetchedPropertyDescription *fetchedProperty = (NSFetchedPropertyDescription *)property;
                    NSFetchRequest *fetchRequest = [fetchedProperty fetchRequest];
    
                    // Only sort by name if the destination entity actually has a "name" field
                    if ([[[[fetchRequest entity] propertiesByName] allKeys] containsObject:@"name"]) {
                        NSSortDescriptor *sortByName = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
                        [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortByName]];
                        [sortByName release];
                    }
                }
            }
        }
    
        return managedObjectModel;
    }
    
    0 讨论(0)
  • 2020-12-12 16:00

    Put this into your NSManagedObject subclass:

    + (void)initialize
    {
        if (self != [EntityManagedObjectSubClass class]) return;
        NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
        NSEntityDescription *entityDescription = [managedObjectModel entitiesByName][@"entityName"];
        NSFetchedPropertyDescription *fetchedPropertyDescription = [entityDescription propertiesByName][@"fetchedPropertyName"];
        NSFetchRequest *fetchRequest = [fetchedPropertyDescription fetchRequest];
        NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"sortDescriptorKey" ascending:YES];
        [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
    }
    

    Replace EntityManagedObjectSubClass, entityName, fetchedPropertyName and sortDescriptorKey with your own stuff.

    0 讨论(0)
提交回复
热议问题