fetchRequest question - iphone

in core data , I search using fetchRequest and predicate like the following
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"Study"
inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:
#"( StudyID == %# )",self.StudyID]];
NSArray * StudyList = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
how to check if there a return values or not

Do something like:
if(!StudyList){
//handle fetch request error here
} else {
//success!
if([StudyList count] > 0){ //if array not empty
//do stuff with StudyList contents here
NSLog(#"StudyList contents: %#", StudyList);
}
}
Hope that helps.

You check the size of the StudyList array like so:
if ([StudyList count]>0){
//... found at least one Study object
}else{
//... didn't find anything
}
As an aside, you should follow the naming conventions. A variable like StudyList should be written starting with lower case i.e. studyList. By convention, names that start with capital letters indicate some sort of constant e.g. classes, entities, constants etc.

Just read the documentation of the method:
If an error occurs, returns nil. If no
objects match the criteria specified
by request, returns an empty array.

Related

iPhone how to use NSPredicate to filter Core Data by the parent entity?

My core data is defined as this:
user has many events;
event has a single user relationship;
Both user and event are core data entities. The user entity is passed in through a storyboard segue.
I'm trying to configure NSPredicate to populate the detail UITableView for that user with only events for that particular user.
So far I have tried
//does not work
NSPredicate* onlyThisUserPredicate = [NSPredicate predicateWithFormat:#"user == %#",self.appUser];
//does not work
NSPredicate* onlyThisUserPredicate = [NSPredicate predicateWithFormat:#"SELF.user == %#",self.appUser];
What is the proper syntax to compare events and only return those that have user object equal to the specified user object?
UPDATE:
I'm trying to be able to add events to the user with this kind of fetched results controller:
-(NSFetchedResultsController*)fetchedResultsController
{
if (__fetchedResultsController != nil) {
return __fetchedResultsController;
}
// Set up the fetched results controller.
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Event" inManagedObjectContext:[Event managedObjectContext]];
[fetchRequest setEntity:entity];
// Set the batch size to a suitable number.
[fetchRequest setFetchBatchSize:20];
//I need to configure this user
NSPredicate* onlyThisUserPredicate = [NSPredicate predicateWithFormat:#"user = %#",self.appUser];
// The first sort key must match the section name key path key if present, otherwise the initial dataset would be messed up: rows in incorrect sections
NSString* firstSortKey = #"createDate";
NSSortDescriptor *firstSortDescriptor = [[NSSortDescriptor alloc] initWithKey:firstSortKey ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:firstSortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[fetchRequest setPredicate:onlyThisUserPredicate];
// 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:[Event managedObjectContext] sectionNameKeyPath:nil cacheName:#"Events"];
self.fetchedResultsController = aFetchedResultsController;
aFetchedResultsController.delegate = self;
// [aFetchedResultsController release];
[sortDescriptors release];
[fetchRequest release];
NSError *error = nil;
if (![__fetchedResultsController performFetch:&error]) {
/*
Replace this implementation with code to handle the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
*/
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
// abort();
}
return __fetchedResultsController;
}
Thank you!
OK, there are a couple of things that I can think of that might cause this behavior.
First, have you validated the value of self.appUser within this function? Is it set to what you expect?
Second, have you made sure your headers are all up to date and included in this file? Sometimes I've experienced odd behavior when my headers aren't up to date with the coredata model.
So this predicate is for the User entity correct? If so, did you try this:
NSPredicate* onlyThisUserPredicate = [NSPredicate predicateWithFormat:#"SELF == %#",self.appUser];
Then you could access your events through:
[self.appUser events];
If you've already retrieved the 'user' from the Core Data store, then you should be able to access its events simply by following that relationship -- no need to do a separate fetch request:
NSSet *events = self.appUser.events;
On the other hand, if self.appUser isn't a managed object, then using the == operator in your predicate is probably the problem. So let me assume that self.appUser is just a string containing the name of the user, not the user object from the data store. Then you'd use the 'like' operator in your predicate:
NSPredicate* onlyThisUserPredicate = [NSPredicate predicateWithFormat:#"user like %#",self.appUser];
Also, be sure that you've specified the right entity in your fetch request. For what you've described, you should be doing the fetch with the entity description for your event entity.

Help me to get the result based on condition

I have created a Users class based on NSManagedObject with following attributes (id,name,age etc).
I am using the core data model but i am not sure how to do the follwing...
Now i would like to know How can i get the user detail based on user id.
example: select * from users where id = 1
please help me out.
You should use NSPredicate class for executing SQL commands. The code:
NSManagedObjectContext *context = self.managedObjectContext; // specify your MOC object
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"users" inManagedObjectContext:context]; // specify your entity (table)
NSPredicate *predicate = [NSPredicate predicatewithFormat:#"id == %d",yourID]; // specify your condition (predicate)
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:predicate];
NSError *error = nil;
NSArray *array = [context executeFetchRequest:fetchRequest error:&error]; // execute
[entity release];
[predicate release];
[fetchRequest release];
if (array == nil) {
// Error: no objects returned
} else {
// Success: do whatever you want
}
Step 1: Alloc/init NSFetchRequest
You need to alloc/init a NSFetchRequest object if you want to execute queries.
Step 2: Select entity
If you want to specify select * from users ..., you should use NSEntityDescription:
NSEntityDescription *entity = [NSEntityDescription entityForName:#"users" inManagedObjectContext:context];
At the end you need to 'attach' your entity description to your NSFetchRequest object via:
[fetchRequest setEntity:entity];
Step 3: Condition
If you want to have a condition (e.g. ... where id = 1), you have to implement NSPredicate.
NSPredicate *predicate = [NSPredicate predicatewithFormat:#"id == %d",yourID];
yourID must be a number (e.g. 1, 2, 7 or 46).
And, again:
[fetchRequest setPredicate:predicate];
Step 4: Let's execute it!
NSArray *array = [context executeFetchRequest:fetchRequest error:&error];
All the records that meet the conditions will be returned as array of NSManagedObjects.
Step 5: Release objects
[entity release];
[predicate release];
[fetchRequest release];
Step 6: Do something
If there are no objects that meet the conditions, array object will be nil. You can check it and deal with the error via:
if (array == nil)
Check out Core Data Programming Guide for more info. :)

why wont this NSPredicate work?

i have a list of objects being managed by CoreData. i want to get a specific object out of CoreData using an NSPredicate. below is the code i am using. Array arr always comes back with 0 objects in it presumably because the fetch cant find an object that matches the predicate. i know for a fact that at least 1 object in CoreData has an advertisement.uuid that matches adUdid. i have manually gotten the entire list of objects and searched it myself for the uuid and found it. advertisement is a member of WebServiceAuthService_mobileAdvertisementVO and uuid is a member of advertisement. whats even more aggregating is the fact that this exact code works just fine in another project. im at a loss to figure out why this code no longer works in the new project.
incase it matters this code is in a static library i am making.
EDIT: arr is always empty so there is nothing to post. there are also no errors being given. its just not working. the uuids are NSStrings something along the lines of "9ca98efe-ef48-47c0-aff5-058224b3093d". i have a feeling the problem may be elsewhere in the code and just manifesting itself here.
WebServiceAuthService_mobileAdvertisementVO *mobileAd = nil;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"WebServiceAuthService_mobileAdvertisementVO" inManagedObjectContext:managedObjectContext];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"advertisement.uuid == %#",adUdid];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:predicate];
NSError *error = nil;
NSArray *arr = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
[fetchRequest release];
if (error)
{
DLog(#"fetched special ad error: %#",[error localizedDescription]);
}
if (arr && [arr count] >= 1)
{
DLog(#"found ad with UUID %#",adUdid);
for (WebServiceAuthService_mobileAdvertisementVO *obj in arr)
{
NSManagedObjectID *objID = [obj objectID];
if (![objID isTemporaryID])
{
mobileAd = obj;
}
}
}
You are comparing strings, in which case LIKE is a better operator than ==. So:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"advertisement.uuid LIKE %#",adUdid];
Don't worry about quotes, predicateWithFormat: will automatically put single quotes around the right hand term.
EDIT:
Reference: Predicate Programming Guide

fetching objects from core data not in a set

I'm trying to fetch objects from core data that are not in a given set, but I haven't been able to get it to work.
For instance, suppose that we have a core data entity named User, which has a few attributes such as userName, familyName, givenName, and active. Given an array of strings representing a set of usernames, we can easily fetch all the users corresponding to that list of usernames:
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"User"
inManagedObjectContext:moc];
[request setEntity:entity];
NSArray *userNames = [NSArray arrayWithObjects:#"user1", #"user2", #"user3", nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"userName IN %#", userNames];
[request setPredicate:predicate];
NSArray *users = [moc executeFetchRequest:request error:nil];
However, I want to fetch the complement of that set, i.e., I want all the users in core data that don't have the usernames specified in the userNames array. Does anyone have an idea how to approach this issue? I thought it would be simple enough to add a "NOT" in the predicate (i.e., "userName NOT IN %#"), but Xcode throws an exception saying the predicate format could not be parsed. I also tried using the predicate builder available for fetch requests with no luck. The documentation wasn't particularly helpful either. Suggestions? Comments? Thanks for all your help :)
In order to find the objects that aren't in your array, all you have to do is something like this:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"NOT (userName IN %#)", userNames];
That should return a request of all the objects without the ones you specified
I am not strong at core data/objective-c but the predicate should be like the following statement;
[predicateFormat appendFormat:#"not (some_field_name in {'A','B','B','C'})"];
An example:
NSMutableString * mutableStr = [[NSMutableString alloc] init];
//prepare filter statement
for (SomeEntity * e in self.someArray) {
[mutableStr appendFormat:#"'%#',", e.key];
}
//excluded objects exist
if (![mutableStr isEqual:#""])
{
//remove last comma from mutable string
mutableStr = [[mutableStr substringToIndex:mutableStr.length-1] copy];
[predicateFormat appendFormat:#"not (key in {%#})", mutableStr];
}
//...
//use this predicate in NSFetchRequest
//fetchRequest.predicate = [NSPredicate predicateWithFormat:predicateFormat];
//...
Here's another useful example, showing how to take a list of strings, and filter out any which DON'T start with the letters A-Z:
NSArray* listOfCompanies = [NSArray arrayWithObjects:#"123 Hello", #"-30'c in Norway", #"ABC Ltd", #"British Rail", #"Daily Mail" #"Zylophones Inc.", nil];
NSPredicate *bPredicate = [NSPredicate predicateWithFormat:#"NOT (SELF MATCHES[c] '^[A-Za-z].*')"];
NSArray *filteredList = [listOfCompanies filteredArrayUsingPredicate:bPredicate];
for (NSString* oneCompany in filteredList)
NSLog(#"%#", oneCompany);
I use this kind of NSPredicate when I'm populating a UITableView with an A-Z index, and want an "everything else" section for items which don't start with a letter.

Using NSPredicate to get an array of Core Data objects?

Say I have a Core Data entity called Person. How would I get an NSArray of Persons whose properties match certain values? For instance someone of a particular age, height, or weight... or someone with a whose height,weight and age are specific values...
Can I use an NSPredicate like so:
NSPredicate *pred =
[NSPredicate predicateWithFormat:
#"(age == 25) OR (height_in_cms == 185) OR (age == 30 AND height_in_cms == 170 AND weight_in_kgs == 80)";
// All properties are NSNumber
I'm not an expert on the syntax for predicateWithFormat:, but you have the basic gist. You can find details on the format in Apple's Predicate Programming Guide. If you're asking what to do with the predicate once you have it, here is a snippet that shows you the steps:
// Create a fetch request.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Set the entity for the fetch request.
NSEntityDescription *entity = [NSEntityDescription entityForName:#"EntityName" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
[entity release];
// Set the predicate for the fetch request.
[fetchRequest setPredicate:predicate];
// Perform the fetch.
NSError *error;
NSArray *array = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
[fetchRequest release];
If you want the results to be sorted, you can pass an array of sort descriptors to the fetch request using setSortDescriptors: prior to executing the fetch.
You can follow the given statement if you have these value in a variable.
[fetchResults filterUsingPredicate:[NSPredicate predicateWithFormat:#"age == %i OR hieght== %i AND weight==%i",age,height,weight]];
And also your approach is correct in case for specific values but your statement having syntax error so maintain proper syntax