How to use Coredata ordered relationships with NSFetchedResultsController

  • I have an Items Entity and a Tags Entity.
  • Items can have multiple Tags and Tags can be linked to multiple Items (many to many relationship).
  • The relationship is an "Ordered Relationship" (using Ordered relationship in IOS5) both ways.
  • I want to fetch all Items for a Tag using a NSFetchedResultsController.

    Queries:

  • Is it even possible to use ordered relationships with NSFetchRequest and NSFetchedResultsController?
  • How do I specify the "Sort Descriptor"?
  • I tried two predicates. The first did not give any results, the second one did give results. Why does the first one does not work? Again how do I specify the sort descriptor to use the sorted order managed automatically by CoreData for this relationship?
  • Did not work: [NSPredicate predicateWithFormat:@"ANY tags == %@", yyy];

    Worked: But less efficient: [NSPredicate predicateWithFormat:@"ANY tags.tagID == %@", xxx];


    1 - Yes. It is possible. When you create your mapping file, make sure you change the relationship's type from an NSSet to an NSArray, like so:

        @class Tags
    
        @interface Entity : NSManagedObject
        ...
        @property (nonatomic, retain) NSOrderedSet *tags;
        ...
        @end
    
        @interface Entity (CoreDataGeneratedAccessors)
        ...
        - (void)addEntityTags:(NSOrderedSet *)values;
        - (void)removeEntityTags:(NSOrderedSet *)values;
        ...
        @end
    

    Change to:

        @class Tags
    
        @interface Entity : NSManagedObject
        ...
        @property (nonatomic, retain) NSArray *tags;
        ...
        @end
    
        @interface Entity (CoreDataGeneratedAccessors)
        ...
        - (void)addEntityTags:(NSArray *)values;
        - (void)removeEntityTags:(NSArray *)values;
        ...
        @end
    

    2 - You can specify a sort descriptor when creating your fetch request, like so:

        NSFetchRequest *fetchRequest [NSFetchRequest new];
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Entity" inManagedObjectContext:myManagedObjectContext];
    
        [fetchRequest.setEntity: entity];
        [fetchRequest setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"tags" ascending:<YES|NO>]];
        [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"ANY tags == %@", yyy]];
    
        NSFetchResultsController *myFetchResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:myManagedObjectContext setcionNameKeyPath:nil cacheName:nil];
        myFetchResultsController.delegate = self;
    
        [fetchRequest release]; // Forget that if using ARC.
    
        NSError *error = nil;
    
        if (![myFetchResultsController performFetch:&error]) {
            NSLog(@"Failed to fetch data: %@", error);
        }
    

    3 - If you use the property, you shouldn't need to specify a predicate for your tags. If you want to further sort your tags, you can simply use a sort descriptor on that array, like this:

        NSSortDescriptor *tagDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"<tags field to sort on>" ascending:<YES|NO>];
        NSArray *sortedTags = [tagsProperty sortedArrayUsingDescriptors:[NSArray arrayWithObject:descriptors]];
    

    You can simply read from that property for your tags.

    Hope this helps!

    链接地址: http://www.djcxy.com/p/36146.html

    上一篇: 核心数据中的位置通过NSFetchedResultsController按距离排序?

    下一篇: 如何使用Coredata与NSFetchedResultsController的有序关系