NSPredicate with localizedCaseInsensitiveCompare - core-data

I have an App with CoreData and I need to use NSPredicate to retrieve all the contacts from a city.
The question is that "city" maybe written like LONDON or London or even london. And the user will type London to search, or LoNDon.
What I need is to use NSPredicate with localizedCaseInsensitiveCompare, so that all the records are retrieved.
Code:
request.predicate = [NSPredicate predicateWithFormat:
#"activityDeleted == %# && (SUBQUERY(hasMembers, $sub, $sub.memberDeleted == %#).#count > 0) && (SUBQUERY(hasMembers, $sub, $sub.city == %#)",
[NSNumber numberWithBool:NO],
[NSNumber numberWithBool:NO],
city];
The above NSPredicate retrieves all the groups that have Contacts, not deleted, that are in a certain City, but I have the CaseInsensitive problem...
How can I do that?
Thanks,
RL

You don't need subquery here. Your entire predicate can instead be:
#"activityDeleted == NO AND ANY hasMembers.memberDeleted = NO AND ANY hasMembers.city =[cd] %#", city

You can use the case insensitive and diacritic insensitive modifiers "[cd]" on the ==
SUBQUERY(hasMembers, $sub, $sub.city ==[cd] %#)
You might try searching stackoverflow for "case insensitive nspredicate" there are several answers already https://stackoverflow.com/search?q=case+insensitive+nspredicate

Related

Is a subquery needed for my nspredicate to work properly?

I have an array of custom objects that have beds (1,2,3), fireplace (yes or no), den (yes or no) and ceiling heights (9-11,11-14,14-16). I need to allow filtering based on any/all/none of the items being selected to filter by. So a user may want to see 1 & 2 beds, den, fireplace and 9-11 foot ceilings. Or just 1 & 2 beds. My current predicate works for some of these. But it doesn't match all - only some. I am thinking I need a subquery. How to create a nested(?) subquery based on an array of filters?
Right now, the user selects buttons and those are matched against Filters and I use those to create my predicate.
Current predicate
Filters is an array of keys and predicate strings like 'beds, 1' and 'ceilings, 9-11'
`NSMutableArray *subPredicates = [NSMutableArray array];
for (Filter*fil in filters) {
NSPredicate *unitsPredicate = [NSPredicate predicateWithFormat:#"%K == %#", fil.key, fil.predicate];
[subPredicates addObject:bedsPredicate];
}
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:subPredicates];
NSLog(#"homes: %#", [searchArray filteredArrayUsingPredicate:predicate]);
NSArray *ar = [searchArray filteredArrayUsingPredicate:predicate];
I'd like to allow someone to pick any of the criteria and return appropriate data.
Subqueries are used with to-many relationships. If you want to filter multiple values then the class of fil.predicate should be an array (or set) of values. The predicate format is %K IN %#, for example
for (Filter*fil in filters) {
NSPredicate *unitsPredicate;
if ([fil.predicate isKindOfClass:[NSArray class]])
unitsPredicate = [NSPredicate predicateWithFormat:#"%K IN %#", fil.key, fil.predicate];
else
unitsPredicate = [NSPredicate predicateWithFormat:#"%K == %#", fil.key, fil.predicate];
[subPredicates addObject:bedsPredicate];
}
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:subPredicates];
See Aggregate Operations in Predicate Programming Guide.

how TRUEPREDICATE differ from [NSPredicate predicateWithValue:YES]?

I am using [fetchRequest setPredicate:[NSPredicate predicateWithValue:YES]]; to debug my code to by pass universal true predicate.
When I exicuting lldb command po [NSPredicate predicateWithValue:YES], it print TRUEPREDICATE.
The return type for predicateWithValue: is NSPredicate.
When I changed it to [fetchRequest setPredicate:TRUEPREDICATE]; Xcode complain a syntax error "use of un-declared identifier"
My question is should I have to import any header file to remove error? If not then how TRUEPREDICATE differ from [NSPredicate predicateWithValue:YES].
A universal true predicate can be created with
[NSPredicate predicateWithValue:YES];
or
[NSPredicate predicateWithFormat:#"TRUEPREDICATE"];
Both statements return the same predicate.
po prints the description of an object. The description of NSPredicate is similar to the format.
in Swift 3 you would do as below
NSPredicate(value: true)
or
NSPredicate(format: "TRUEPREDICATE")

predicateWithFormat:argumentArray: Using all items in NSArray

- (void)filterViaCategories:(NSArray *)array {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(todo_category_id == %#)" argumentArray:array];
}
but when I have used:
po predicate
Result is:
todo_category_id == 41123..
It just using 41123 from zero index element of array
i want all categories from data base for all id present in array not the only object at index zero:
(todo_category_id == 41123, 41234, 33455) etc.
How can I do this?
Then you should not be using predicateWithFormat:argumentArray: and you need to change your format.
You want something like:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"todo_category_id IN %#", array];

Core Data NSPredicate with to-Many Relationship

I have two Entities in CoreData called User and Coupon, they are in Many-to-Many relationship. I wanted to fetch for all Coupons except those owned by user.userId = 1, where userId is NSString.
I used:
[NSPredicate predicateWithFormat:#"NOT(ANY couponOwners.userId = %#)", #"4"];
to be the predicate of my fetchedResultsController
but not filtering with correct results. One of the User in couponOwners of the Coupon is still having userId = 4.
Could somebody please help? I have been stuck for quite a while. Thanks in advance.
Core Data predicates with "NOT ANY" do not work (that seem to be a Core Data bug). Actually
[NSPredicate predicateWithFormat:#"NOT(ANY couponOwners.userId = %#)", #"4"];
returns the same result set as
[NSPredicate predicateWithFormat:#"ANY couponOwners.userId != %#", #"4"];
which is of course wrong. As a workaround, you can use a SUBQUERY:
[NSPredicate predicateWithFormat:#"SUBQUERY(couponOwners, $c, $c.userId == %#).#count == 0", #"4"]

CoreData - NSPredicate results if relationship has data

I have a many-to-many relationship between tables, and I populate a tableView with Activities.
For that i user a simple NSPredicate like this:
request.predicate = [NSPredicate predicateWithFormat:#"deleted == %#", [NSNumber numberWithBool:NO]];
How can I do to show only the Activities that has Members attached to it?
I think that in the NSPredicate I have to do some count so that only the Activities with count > 0 are returned. Is that so?
How?
(i'm newbie in coredata...)
Thanks,
RL
You need to add a subquery to your predicate acting on the CompanyActivity entity as follows:
[[NSPredicate predicateWithFormat:#"deleted == %#" && (0 >= SUBQUERY(Members, $sub, $sub.deleted == %#).#count)", [NSNumber numberWithBool:NO] [NSNumber numberWithBool:NO]];
The first part of the predicate returns objects which have not been deleted, the second one related to the subquery will take care of retrieving all those CompanyActivity objects whose Members have not been deleted.

Resources