Core Data NSPredicate for relationships

32,699

Solution 1

The key here is "ANY"

Example from apple:

NSPredicate *predicate = [NSPredicate predicateWithFormat:
    @"ANY employees.firstName like 'Matthew'"];

http://developer.apple.com/mac/library/documentation/cocoa/conceptual/CoreData/Articles/cdBindings.html

Solution 2

Do you require SQLite? I am grappling with a similar issue, and have found that everything works as expected with a binary store.
There are limitations when using SQLite as a store, though I have not yet found a document that lists the limitations, only that they exist.

Sorry I can't be of more help.

Share:
32,699
Mugunth
Author by

Mugunth

iOS Developer/Author/Blogger and Usability Guy. http://blog.mugunthkumar.com Co-author of the book iOS Programming: Pushing the Limits I will not answer your question here on Stackoverflow if you ask anything about Iphone or IPHONE or I-phone.

Updated on July 09, 2022

Comments

  • Mugunth
    Mugunth almost 2 years

    My object graph is simple.

    I've a feedentry object that stores info about RSS feeds and a relationship called Tag that links to "TagValues" object. Both the relation (to and inverse) are to-many. i.e, a feed can have multiple tags and a tag can be associated to multiple feeds.

    I referred to How to do Core Data queries through a relationship? and created a NSFetchRequest. But when fetch data, I get an exception stating,

    NSInvalidArgumentException unimplemented SQL generation for predicate

    What should I do? I'm a newbie to core data :( I know I've done something terribly wrong... Please help...

    Thanks

    --

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"FeedEntry" inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];
    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"authorname" ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    
    [fetchRequest setSortDescriptors:sortDescriptors];
    
    NSEntityDescription *tagEntity = [NSEntityDescription entityForName:@"TagValues" inManagedObjectContext:self.managedObjectContext];
    NSPredicate *tagPredicate = [NSPredicate predicateWithFormat:@"tagName LIKE[c] 'nyt'"];          
    NSFetchRequest *tagRequest = [[NSFetchRequest alloc] init];
    [tagRequest setEntity:tagEntity];
    [tagRequest setPredicate:tagPredicate];
    
    NSError *error = nil;
    NSArray* predicates = [self.managedObjectContext executeFetchRequest:tagRequest error:&error];
    
    
    TagValues *tv = (TagValues*) [predicates objectAtIndex:0];
    NSLog(tv.tagName); // it is nyt here...
    
    
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"tag IN %@", predicates];
    [fetchRequest setPredicate:predicate];
    
    
    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"];
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController; 
    

    --

    • catsby
      catsby almost 15 years
      post some of your code so we can have a better look
    • Barry Wark
      Barry Wark almost 15 years
      Mungunth, it looks like you may be forgetting to set the entity of the fetchRequest after re-setting the predicate to 'tag IN predicates'. If this isn't the issue, please also post a pic of the object model and I can give you a bit more guidance.
    • Mugunth
      Mugunth almost 15 years
      I got the answer through devforums.apple.com. Till the NDA is in place, I can't divulge the answer... :(
  • Mugunth
    Mugunth almost 15 years
    Yes, it works with a binary store. I used a sql lite db as it seems to be faster in my case. I deal with data of sizes close to 5MB (on iPhone). App loading time is < 1sec for sqlite where as it's close to 2 sec for binary store.
  • Mugunth
    Mugunth almost 15 years
    I foudn the answer though... NSPredicate *predicate = [NSPredicate predicateWithFormat:@"tag IN %@", predicates]; [fetchRequest setPredicate:predicate]; should be changed to NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY tag IN %@", predicates]; [fetchRequest setPredicate:predicate];
  • emp
    emp almost 15 years
    Good to know - it's strange, your message is very similar to one I had, and yet mine is due to a limitation of Core Data with SQLite. Know to figure out how to tell the difference!