NSFetchedResultsController with sections created by first letter of a string

后端 未结 7 1496
再見小時候
再見小時候 2020-11-28 01:09

Learning Core Data on the iPhone. There seem to be few examples on Core Data populating a table view with sections. The CoreDataBooks example uses sections, but they\'re ge

7条回答
  •  自闭症患者
    2020-11-28 01:37

    Dave DeLong's approach is good, at least in my case, as long as you omit a couple of things. Here's how it's working for me:

    • Add a new optional string attribute to the entity called "lastNameInitial" (or something to that effect).

      Make this property transient. This means that Core Data won't bother saving it into your data file. This property will only exist in memory, when you need it.

      Generate the class files for this entity.

      Don't worry about a setter for this property. Create this getter (this is half the magic, IMHO)


    // THIS ATTRIBUTE GETTER GOES IN YOUR OBJECT MODEL
    - (NSString *) committeeNameInitial {
        [self willAccessValueForKey:@"committeeNameInitial"];
        NSString * initial = [[self committeeName] substringToIndex:1];
        [self didAccessValueForKey:@"committeeNameInitial"];
        return initial;
    }
    
    
    // THIS GOES IN YOUR fetchedResultsController: METHOD
    // Edit the sort key as appropriate.
    NSSortDescriptor *nameInitialSortOrder = [[NSSortDescriptor alloc] 
            initWithKey:@"committeeName" ascending:YES];
    
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:nameInitialSortOrder]];
    
    NSFetchedResultsController *aFetchedResultsController = 
            [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
            managedObjectContext:managedObjectContext 
            sectionNameKeyPath:@"committeeNameInitial" cacheName:@"Root"];
    

    PREVIOUSLY: Following Dave's initial steps to the letter generated issues where it dies upon setPropertiesToFetch with an invalid argument exception. I've logged the code and the debugging information below:

    NSDictionary * entityProperties = [entity propertiesByName];
    NSPropertyDescription * nameInitialProperty = [entityProperties objectForKey:@"committeeNameInitial"];
    NSArray * tempPropertyArray = [NSArray arrayWithObject:nameInitialProperty];
    
    //  NSARRAY * tempPropertyArray RETURNS:
    //    {type = immutable, count = 1, values = (
    //    0 : (), 
    //    name committeeNameInitial, isOptional 1, isTransient 1,
    //    entity CommitteeObj, renamingIdentifier committeeNameInitial, 
    //    validation predicates (), warnings (), versionHashModifier (null), 
    //    attributeType 700 , attributeValueClassName NSString, defaultValue (null)
    //    )}
    
    //  NSInvalidArgumentException AT THIS LINE vvvv
    [fetchRequest setPropertiesToFetch:tempPropertyArray];
    
    //  *** Terminating app due to uncaught exception 'NSInvalidArgumentException',
    //    reason: 'Invalid property (), 
    //    name committeeNameInitial, isOptional 1, isTransient 1, entity CommitteeObj, 
    //    renamingIdentifier committeeNameInitial, 
    //    validation predicates (), warnings (), 
    //    versionHashModifier (null), 
    //    attributeType 700 , attributeValueClassName NSString, 
    //    defaultValue (null) passed to setPropertiesToFetch: (property is transient)'
    
    [fetchRequest setReturnsDistinctResults:YES];
    
    NSSortDescriptor * nameInitialSortOrder = [[[NSSortDescriptor alloc]
        initWithKey:@"committeeNameInitial" ascending:YES] autorelease];
    
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:nameInitialSortOrder]];
    
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] 
        initWithFetchRequest:fetchRequest 
        managedObjectContext:managedObjectContext 
        sectionNameKeyPath:@"committeeNameInitial" cacheName:@"Root"];
    

提交回复
热议问题