NSPredicate query for not containing a specific string - ios

Looked high and low for this one but can't find my answer. I am looking to query core data for all records which are NOT equal to a specified string. For example, all records which are not equal to the current session ID. I have tried these to no avail:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"listingID != %#", [sitListingID objectAtIndex:i]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%# NOT CONTAINS[cd] %#",#"listingID", [sitListingID objectAtIndex:i]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%# NOT CONTAINS %#",#"listingID", [sitListingID objectAtIndex:i]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"listingID NOT like %#", [sitListingID objectAtIndex:i]];
Nothing works.HEEEEELP!!!
----------------------------------------------------- more code
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"ListingRecord" inManagedObjectContext:context];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"sessionID <> %#", uniqueSessionListings];
[request setPredicate:predicate];
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[context executeFetchRequest:request error:&error] mutableCopy];

Your first predicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"listingID != %#", sessionID];
should work to find all records where the attribute listingID is not equal to sessionID (provided that listingID and sessionID have the same type).
If both are strings and you want to find all records where listingID does not contain the string sessionID as a substring, then this predicate should work:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"NOT (listingID CONTAINS %#)", sessionID];
Use "CONTAINS[cd]" if the string comparison should be done case and diacritical insensitive.
NOTE: You can specify the attribute name as an argument, but then you must use %K instead of %# as format:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"NOT (%K CONTAINS %#)", #"listingID", sessionID];

Related

Is it possible to do case insensitive fetch in Core Data?

I am trying to execute a fetch request on NSManagedObjectContenxt and I want the predicate to be case insensitive.
I tried several solutions that I found but all of them works only on NSArray (filteredArrayUsingPredicate) but not on Core Data.
For example:
My persistent store contains an NSManagedObject, 'Car', with the attribute 'name' and its value is "GMC".
1) The following returns with an empty array:
NSFetchRequest* fetch = [[NSFetchRequest alloc] init];
fetch.entity = [NSEntityDescription entityForName:#"Car" inManagedObjectContext:moc];
fetch.predicate = [NSPredicate predicateWithFormat:#"name matches[c] %#", #"gmc"];
NSArray* cars = [moc executeFetchRequest:fetch error:nil];
2) The following crashes with 'EXC_BAD_ACCESS':
fetch.predicate = [NSPredicate predicateWithFormat:#"name ==[c] %#", #"gmc"];
NSArray* cars = [moc executeFetchRequest:fetch error:nil];
3) The only fetch that works is:
fetch.predicate = [NSPredicate predicateWithFormat:#"name == %#", #"GMC"];
NSArray* cars = [moc executeFetchRequest:fetch error:nil];
Is it possible to do case insensitive fetch in Core Data? And how?
Thanks.
Try below code:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"UPC ==[c] %# OR ItemID ==[c] %#", aUPCCode,aUPCCode];
The keywords "like" and "contains" seem to work just fine.
fetch.predicate = [NSPredicate predicateWithFormat:#"name like[c] %#", #"gmc"];
or
fetch.predicate = [NSPredicate predicateWithFormat:#"name contains[c] %#", #"gmc"];
More keyword options and details can be found here:
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html#//apple_ref/doc/uid/TP40001795-CJBDBHCB
and here
http://nshipster.com/nspredicate/
Use #selector(caseInsensitiveCompare:) with your fetchRequest like:
NSSortDescriptor *sortDescr = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES selector:#selector(caseInsensitiveCompare:)];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Car"];
[fetchRequest setSortDescriptors:#[sortDescr]];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"name matches[c] %#", #"gmc"]];
Then perform your fetch as usual.

NSFetchRequest using NSPredicate

I am trying to create a NSArray of all results of a filtered search through a core data database in this way:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"AllFiles" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *p1 = [NSPredicate predicateWithFormat:#"userID == %#", userID];
NSPredicate *p2 = [NSPredicate predicateWithFormat:#"folderNumber == %d", folderNumber];
NSPredicate *p3 = [NSPredicate predicateWithFormat:#"fileType == %#", type];
NSPredicate *fetchPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:#[p1, p2, p3]];
[fetchRequest setPredicate:fetchPredicate];
NSError *error;
NSArray* returnArray = [context executeFetchRequest:fetchRequest error:&error];
The files are created in this way:
AllFiles *newFile = [NSEntityDescription
insertNewObjectForEntityForName:#"AllFiles"
inManagedObjectContext:context];
newFile.userID = userID;
newFile.folderNumber = [NSString stringWithFormat:#"%d", folderNumber];
....
As you can see I am trying to filter the results given some of the parameters:
#"userID == %#", userID
However all results are returned, without filtering... Any ideas why?
You are using an OR predicate, at least one of those 3 is matching for all. I suspect [NSPredicate predicateWithFormat:#"fileType == %#", type] is gathering all your files
Try compositing an AND like so...
NSPredicate *idPredicate = [NSPredicate predicateWithFormat:#"userID == %#", userID];
NSPredicate *folderNumPredicate = [NSPredicate predicateWithFormat:#"folderNumber == %d", folderNumber];
NSPredicate *typePredicate = [NSPredicate predicateWithFormat:#"fileType == %#", type];
NSPredicate *fetchPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:#[idPredicate, folderNumPredicate, typePredicate];
[fetchRequest setPredicate:fetchPredicate];
Bear in mind that andPredicateWithSubpredicates and orPredicateWithSubpredicates return a NSPredicate so they can be composited together in complex ways if you need.

NSPredicate returning all objects

I'm trying to use the NSPredicate to only get specific objects. The problem is that all the objects are fetched and it should only be specific objects where the condition is correct.
- (void)fetchDevices {
// Fetch the devices from persistent data store
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Songs"];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Songs" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
// retrive the objects with a given value for a certain property
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"selectedRow == %#" , selectedRowNumber];
devices = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
[fetchRequest setPredicate:predicate];
}
The selectedRowNumber is an int declared in the .h file.
A look on my Songs entity:
PS. Please comment below if more information is required and i'll provide it.
You have to assign the predicate before executing the fetch request.
Also, if selectedRowNumber is an int then you have to use the %d format
instead of %#.
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"selectedRow == %d" , selectedRowNumber];
[fetchRequest setPredicate:predicate];
devices = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
Try this,
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"selectedRow = %#" , [NSNumber numberWithInt: selectedRowNumber]];
[fetchRequest setPredicate:predicate];
devices = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
there seems to be two problems.
I think you need to put [fetchRequest setPredicate:predicate]; before devices = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
Also #"selectedRow == %d" seems not right. You may want to change it to #"selectedRow = %d"
And no need to set entity again.
So the code may look like this.
- (void)fetchDevices {
int selectedRowNumber = 1;
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Songs"];
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"selectedRow = %d" , selectedRowNumber];
[fetchRequest setPredicate:predicate];
NSArray *devices = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
}
Let me know how it goes :)
There is no need of setting Entity using setEntity.
[fetchRequest setPredicate:predicate]
Just set predicate, it will work.
- (void)fetchDevices {
// Fetch the devices from persistent data store
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Songs"];
// retrive the objects with a given value for a certain property
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"selectedRow == %#" , selectedRowNumber];
[fetchRequest setPredicate:predicate];
devices = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
[fetchRequest setPredicate:predicate];
}

How can I use predicateWithFormat for query a NSString is contained in an NSSet

Using StackMob as backend. I have an Event entity which has a relationship called user users (type NSSet). Right now I want to get all the events that some user's username is #"someuser". My code like this:
[self.client getLoggedInUserOnSuccess:^(NSDictionary *result) {
NSString *currentlyLoggedInUser = [result valueForKey:#"username"];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *eventEntity = [NSEntityDescription entityForName:#"Event" inManagedObjectContext:self.managedOjbectContext];
[request setEntity:eventEntity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ANY users.username = %#", currentlyLoggedInUser];
NSLog(#"predicate: %#", predicate);
[request setPredicate:predicate];
NSLog(#"request: %#", request);
events = [NSArray new];
events = [self.managedOjbectContext executeFetchRequest:request error:nil];
/* this is working...
for (Event *e in events) {
NSLog(#"%#",[e.users filteredSetUsingPredicate:[NSPredicate predicateWithFormat:#"username == %#", currentlyLoggedInUser]]);
}
*/
NSLog(#"events: %#", events);
} onFailure:^(NSError *error) {
}];
If I understand your question correctly, you have to use the following predicate:
NSString *userName = #"some user";
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ANY users.username = %#", userName];
It finds all events that have any user with the given user name.
Assuming you have a User entity and an Event entity, you have to pass a User to the predicate, not just the name.
User *loggedInUser = // anything, e.g.
User *loggedInUser = [[allUsers filteredSetUsingPredicate:
[NSPredicate predicateWithFormat:
#"username == %#", currentlyLoggedInUser] anyObject];
fetchRequest.predicate = [NSPredicate predicateWithFormat:
#"%# in users", loggedInUser]

NSPredicate over different entities

I want to make NSPredicate over different entities. Here is my core database.
To make it simple, this is the query I should do.
Select c.c_name From Company c, Person p Where c.c_id = p.cu_company_id
Now I was wondering how my predicate should look like if I want to achieve the result like the query above.
Assuming that c_id and cu_company_id are integers, you can try
NSFetchRequest *fr = [[NSFetchRequest alloc] initWithEntityName:#"Person"];
NSError *error;
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"cu_company_id == data.company.c_id"];
[fr setPredicate:predicate];
NSArray *persons = [self.managedObjectContext executeFetchRequest:fr error:&error];
and once you have persons array, you can then loop through it and get the person's name. To get it the other way around
NSFetchRequest *fr = [[NSFetchRequest alloc] initWithEntityName:#"Company"];
NSError *error;
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"c_id == data.person.cu_company_id"];
[fr setPredicate:predicate];
NSArray *companies = [self.managedObjectContext executeFetchRequest:fr error:&error];
and once you have companies array, you can then loop through it and get the company's name.

Resources