NSPredicate fetch coredata - ios

I have two linked types in my CoreData model.
FlightRecording and AHRSMessage
One FlightRecording links to many AHRSMessages.
I've been fetching each recording and iterating through its linked messages:
for (__weak id msgObj in rec.ahrsMessages) {
and have not been seeing the performance I'd like. As I'm fetching the actual recording objects and not the messages I don't believe I can set a batch size on the fetch so I was thinking i'm better off fetching the messages using a correct predicate format.
Assuming I have a NSManagedObjectID for my flight recording is there a quick way to do a predicate query on my AHRSMessage
I've gotten this far which isn't that far:
NSFetchRequest *msgFetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"AHRSMessage" inManagedObjectContext:context];
And then i wasn't sure what to do for my predicate. Do I have to match on an actual field such as:
"ANY flightRecordings = %#" or something like that?
Do I have to reference a specific field in flightRecording or is there a way to just match on the ID?

If "flightRecordings" is a to-many relationship from the AHRSMessage entity to
FlightRecording then this should work:
NSManagedObjectID *flightRecordingId = ...;
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:#"AHRSMessage"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ANY flightRecordings = %#", flightRecordingId];
[fetchRequest setPredicate:predicate];
The argument of the "ANY flightRecordings = %#" predicate can be a FlightRecording object or a NSManagedObjectID of a FlightRecording object.

Related

Core Data: How to fetch Entities based on an attribute of a related entity

This is what the pertinent part of my object graph looks like:
[Anime] <->> [AnimeName #string #type]
So an Anime object has many AnimeName objects that contain a string and the type of name they are. Now to implement a "Search by Name" feature, I would need a predicate that matches all Anime entities where any name contains the search string. What I have tried so far is this:
NSFetchRequest *fetch = [NSFetchRequest fetchRequestWithEntityName:#"Anime"];
[fetch setPredicate:[NSPredicate predicateWithFormat:#"names.string == %#", searchString]];
on an NSFetchRequest of Anime entities, this however gives the following error:
"NSInvalidArgumentException", "to-many key not allowed here"
Which makes perfect sense to me, and I could simply work around that by using this:
NSFetchRequest *fetch = [NSFetchRequest fetchRequestWithEntityName:#"AnimeName"];
[fetch setPredicate:[NSPredicate predicateWithFormat:#"string == %#", searchString]];
and then getting the relationship to the Anime entity from each returned object, but then how do I plug that into an NSFetchedResultsController for my UITableView?
Please help if anyone knows a solution.
For to-many relationships, use "ANY":
NSFetchRequest *fetch = [NSFetchRequest fetchRequestWithEntityName:#"Anime"];
[fetch setPredicate:[NSPredicate predicateWithFormat:#"ANY names.string == %#", searchString]];

objective c - fetch data (core data)

I have two tables Photo and Photographer.
Below is the structure of the tables.
I'm trying to fetch the name of all Photographers who have taken a photo called "Panda".
Here's my code but for some reason it's returning empty.
NSArray *matchingPhotographers;
NSFetchRequest *fetch = [[NSFetchRequest alloc]init];
NSEntityDescription *desc = [NSEntityDescription entityForName:#"Photographer" inManagedObjectContext:context];
[fetch setEntity:desc];
[fetch setPredicate:[NSPredicate predicateWithFormat:#"photo.name like[c] %#",#"Panda"]];
NSError *error;
matchingPhotographers = [context executeFetchRequest:fetch error:&error];
NSLog(#"Photographers: %#", matchingPhotographers);
Am I doing something wrong? The query should definitely return at least 1 photographer.
Thanks
Photo is a collection, so your predicated must be:
[fetch setPredicate:[NSPredicate predicateWithFormat:#"ANY photo.name like[c] %#",#"Panda"]];
This predicate finds "Photographers" which have at list one photo (among his photo's collection) with the name like "Panda".
photo is a to-many relationship so it's easier to use a subquery predicate to count the photos in the relationship which match your criteria:
#"SUBQUERY(photo, $p, $p.name ==[c] %#).#count > 0", #"Photo"
Note I'm also not using LIKE so it isn't a regex comparison.

Core Data fetching many-to-one relationship objects

In my app I have two entities which are Items and Lists. Each item belongs to only one list and each list has many items. Thus in the modal the entities has the following relationships:
For Items: to-one relationship (belongs_to_list) pointing to one list
For Lists: to-many relationship (has_items) pointing to many items
How can I fetch the items using a predicate to check whether the list it's related to is equal to a specific list I provide? I don't want to fetch the items through the list (like fetching objects of has_items). I want to be able to use belongs_to_list in a predicate to compare it to a managed object I have. I tried the following but it's not working. Any help please?
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Items" inManagedObjectContext:_managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"item_detail" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"list.list_name == %#", [self.currentList valueForKey:#"list_name"]];
[fetchRequest setPredicate:predicate];
If I understood well your question, the following predicates would be correct:
[NSPredicate predicateWithFormat:#"belongs_to_list == %#", [self currentList]];
Let me know if this does work for you.

Core Data fetching relationship objects

in my app i have two entities: Members and Lists. they both have a one-to-many relationships (member can have more than one list, list can have more than one member). now i want to fetch the lists belonging to a specific member. here is my code:
WSAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Lists" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:#"has_members contains[cd] %#", [self.currentMember valueForKey:#"name"]]];
[fetchRequest setPredicate:predicate];
NSError *error;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
// Handle the error.
NSLog(#"NO LISTS AVAILABLE IN REFRESH");
}
self.currentMember is a managed object of the user himself.
Note: member has name, (NSSet*) member_of_list
list has list_name, has-members
Problem: when i run the code it's breaking at the fetchedObjects array. i suspect that there is something wrong with the NSPredicate but i don't know where and how to fix it. can any one point out the problem?
First, the relationship you describe between Member (Calling an entity in a plural form is confusing) and List is many-to-many.
Second, instead of using CoreData's inherent object graph capabilities, you went and "rolled your own" relationship between the entities (you should use your interface builder to model a CoreData relationship between the two entities).
See HERE how to do that.
after you model your data, your predicate should look something like:
//Not tested
NSPredicate* p = [NSPredicate predicateWithFormat:#"ANY members = %#",self.currentMember];
DO NOT pass a formatted string to create the predicate, use NSPredicate formatting to substitute parameters or you will not be able to accomplish your goal (in most cases).

Trying to retrieve an Entity using an attribute of the Entity's relationship object as a search criteria in Core Data

I am using Core Data in my application where I am trying to retrieve entities whose relationship objects attribute match my criteria. Unfortunately I am stuck here, because I am passing the id for the relationship object, but I am getting an error saying that the criteria I am passing is not being recognized as an attribute of the entity I am querying.
This is true, because my criteria is actually an attribute for the relationship object, and not an attribute of the entity that I am querying itself. How do I achieve this?
Here is my code:
// Create fetch request
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:myEntityName inManagedObjectContext:context];
[fetchRequest setEntity:entity];
// Create predicate
NSPredicate *pred = [NSPredicate predicateWithFormat:#"relationshipObjectId == %#", relationshipObjectId];//This is where I am having trouble
[fetchRequest setPredicate:pred];
NSArray *items = [context executeFetchRequest:fetchRequest error:&error];
if ([items count]>0) {
return items[0];
} else {
return nil;
}
Can anyone see what it is I am doing wrong?
To find all related objects whose attribute matches a certain value, you would
use a predicate like
[NSPredicate predicateWithFormat:#"rel.attr == %#", value]
where "rel" is the name of the relationship, and "attr" is the name
of the attribute that should match the value.

Resources