NSFetchRequest not working with predicate - iphone

I have this code:
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Entry"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"version == %#", #"1.0"];
[request setPredicate:predicate];
NSArray *results = [managedObjectContext executeFetchRequest:request error:nil];
The entity "Entry" has an attribute called "version", which is a string. The predicate above doesn't seem to only be returning entries with the string as "1.0" though, returning some entries which are set to "1.1".
Am I doing this wrong?

Try putting round braces () around your predicate expression
i.e.
"(version == %#)"

have a look at the apple doc's
and try it with like in case of == or:
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"(version == %#)", #"1.0"];

Related

Core-Data: Predicate for To-Many Relationships to get Object in many related table

In Deals Table the attributes:
ispopular(attribute)
groupname(attribute)
dealsassets(relationship-name to assets)
In Assets Table the attributes are :
assettype(attribute)
caption(attribute)
dealassetid(attribute)
assetsdeal(inverse relationshipname to deals)
Deals is Assets one to many relationship & Assets to Deals many to one relatiosnhip
I want to write a query where i need is ispopular == 1 then that related field's assets.dealasseti,
what predicate query i have to write, could some one help me out.
regards
Is this what you are looking for?
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Assets"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"assetsdeal.ispopular == 1"];
[request setPredicate:predicate];
NSError *error;
NSArray *result = [context executeFetchRequest:request error:&error];
Using the inverse relationship you ask for all assets where the related deal has the property "ispopular == 1".
Alternative Solution (if the first one does not work due to some StackMob restrictions):
Fetch the deals with "ispopular == 1" first:
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Deals"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ispopular == 1"];
[request setPredicate:predicate];
NSError *error;
NSArray *deals = [context executeFetchRequest:request error:&error];
and use Key-Value Coding to get the related assets:
NSArray *assets = [deals valueForKeyPath:#"dealsassets.#distinctUnionOfSets.self"]

NSPredicate using OR error

First time building an NSPredicate.
I would like to search a managedobjectcontext using this logic:
Search for a, grab all matches
Search for b, grab all matches, etc....
Nsarray *results = (has all a results, b results, etc);
My attempted predicate is:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name== %# OR name == %# OR name == %#",a,b,c];
However I get errors with this predicate...
Edited: Sample method I wrote
-(NSPredicate*)parsePartsIntoAPredicate:(NSMutableArray*)inputPartsNames{
NSSet *keys=[NSSet setWithArray:inputPartsNames];
NSPredicate *predicate=[NSPredicate predicateWithFormat:#"any self.#name in %#", keys];
NSLog(#"predicate = %#",predicate);
return predicate;
}
Clarify: I have a database of cars (20,000) Each car has multiple parts. I want to find all cars that have part a, and all cars that have part b, and all that have part c. Then I want to return an array with cars with part a, b, c, etc...
If you think there is a better way let me know, but I am approaching this backwards. I am saying
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Cars" inManagedObjectContext:[self managedObjectContext]];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:[self parsePartsIntoAPredicate:inputParts]];
NSError *error;
NSArray *records = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
What am I doing wrong?
NSString *key;
NSMutableArray *tempArray;
NSPredicate *searchForName = [NSPredicate predicateWithFormat:#"name = %#", key];
NSArray *filterArray = [tempArray filteredArrayUsingPredicate:searchForName];
NSLog(#"%#",filterArray);
Where key is your searchKeyword, tempArray is your CompleteArray in which data is present.
Use Like this. Please put your data.
Use this
NSPredicate* predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:#"%# '%#'", #"SELF contains[c] ",searchText]];
To fetch all Cars objects that have a name which is one of the strings in the keys set or array, use
[NSPredicate predicateWithFormat:#"name IN %#", keys]

What does Unable to generate SQL for predicate (_STRING PREDICATE_) (problem on RHS) mean?

I'm trying to develop an app for iPhone using Core Data and I'm using a very basic predicate to grab objects. (i.e. attribute_name==string)
I've checked the model to make sure the attribute names are correct and I know from this SO question that RHS means "Right Hand Side," which leads me to the "string" part. I'm creating the format string using
NSString *predicateString = [NSString stringWithFormat:#"attribute_name==%#", string];
Then to fetch, I'm using this:
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:_entityName inManagedObjectContext:managedObjectContext];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString];
[request setPredicate:predicate];
NSError *error = nil;
NSArray *array = [managedObjectContext executeFetchRequest:request error:&error];
What am I missing? What could cause this error to occur?
Thanks.
You need to quote the string if you really want to use the NSString stringWithFormat: message or you could use the NSPredicate predicateWithFormat: message with the formatting and arguments because it will "do the right thing" with the rhs in your situation (I would suggest that you use the NSPredicate method without the quotes)
NSString *predicateString = [NSString stringWithFormat:#"attribute_name==\"%#\"", string];
You're doing this wrong. You should not be creating a format string.
I'm guessing (based on your reaction to #Brent's answer) that you're doing something like this:
NSString *predicateString = [NSString stringWithFormat:#"foo == \"%#\"", bar];
NSPredicate *p = [NSPredicate predicateWithFormat:predicateString];
Don't do that.
Do this instead:
NSPredicate *p = [NSPredicate predicateWithFormat:#"foo == %#", bar];
The first will fail if bar happens to contain a " character. The second will not.

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.

How to determine number of objects in one-to-many relationship in CoreData

So, I've got a one-to-many relationship of Companies to Employees in CoreData (using a SQLite backend on iOS, if that's relevant). I want to create a predicate that only returns Companies that have 0 Employees associated with them. I could do it by getting all the Companies and iterating over them, but that would be (I assume) much slower.
Any ideas?
Thanks,
-Aaron
After trying #falconcreek's answer and getting an error (described in my comment on his answer), I did some googling and determined that the answer was
NSPredicate *noEmployeesPredicate = [NSPredicate predicateWithFormat:#"employees.#count == 0"];
Now everything works über efficiently. Thanks!
Assuming your Company -> Employee relationship is named "employees"
NSManagedObjectContext *moc = [self managedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"Company" inManagedObjectContext:moc];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];
// the following doesn't work
// NSPredicate *noEmployeesPredicate = [NSPredicate predicateWithFormat:#"employees = nil OR employees[SIZE] = 0"];
// use #count instead
NSPredicate *noEmployeesPredicate = [NSPredicate predicateWithFormat:#"employees = nil OR employees.#count == 0"];
[request setPredicate:predicate];
NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];
if (error)
{
// Deal with error...
}