NSNumber property of NSManagedObject with NSPredicate - ios

Here I have attribute (name :- universal_Id) in core data as NSNumber in modal class
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"universal_Id == %d",0];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"universal_Id == %d",[NSNumber numberWithInt:0]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"universal_Id == %#",[NSNumber numberWithInt:0]];
Please provide me some correct solution for above predicates. Which one is the correct way to fetch data on the bases of universal_Id?

NSPredicate *predicate = [NSPredicate predicateWithFormat:#"universal_Id == %d",0];
is correct because Core Data is ORM and uses objects to represent scalar values. So when you need to store data in core data , you need to use objects. In predicate building, here you need not to use objects, scalar value is enough to build a predicate, because at the end, core data query matches the universal_Id value, not the object.
Update
you can also use
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.universal_Id == %d",0];

Related

NSPredicate does not return the expected items

I am trying to find an items in the array where itemId and size are not matched.
However, the following query does not return me item(s) where itemId same but size different. I wonder what I am missing.
First I am extracting the item as follows, then I am trying to find compliment of this item.
NSPredicate *itemPredicate = [NSPredicate predicateWithFormat:#"(%K == %#)", kItemId, itemId];
NSPredicate *sizePredicate = [NSPredicate predicateWithFormat:#"(%K == %#)", kSize, [NSString stringWithFormat:#"%d", size]];
NSPredicate *combinedPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:#[itemPredicate, sizePredicate]];
NSArray *itemInOrder = [sharedData.orderItems filteredArrayUsingPredicate:combinedPredicate];
Trying to extract complimentary items of itemInOrder
NSPredicate *restOfOrderPredicate = [NSPredicate predicateWithFormat:#"(%K != %#)", kItemId, itemId];
NSPredicate *restSizePredicate = [NSPredicate predicateWithFormat:#"(%K != %#)", kSize, [NSString stringWithFormat:#"%d", size]];
NSPredicate *restCombinedPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:#[restSizePredicate, sizePredicate]];
NSMutableArray *restOfItemsInOrder = [NSMutableArray arrayWithArray:[sharedData.orderItems filteredArrayUsingPredicate:restOfOrderPredicate]];
I think there are 2 issues here:
Your complementary and predicate is using the sizePredicate, but I think you want to be using restSizePredicate.
I think you want to use an or predicate. As you have it now, you'll miss anything that has just the same size or just the same itemId.
An alternate approach could be to use a fetch that gets all the objects. Then use your existing fetch to get the original set you wanted. Then use Set Arithmetic to remove the second set from the first.
** EDIT **
I just now discovered notPredicateWithSubpredicate which is probably exactly what you want: Keep your first query and predicate as is. Then for the second query, use notPredicateWithSubpredicate and pass in your predicate from the first query.

Filtering values with NSNumber == nil in NSPredicate

I'm trying select values by property with type NSNumber, if property==intValue or property==nil.
But this code ignores values with property==nil.
What the point?
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"(ANY region.beacons.major == %d OR ANY region.beacons.major = nil)
AND (ANY region.beacons.minor == %d OR ANY region.beacons.minor = nil)",
rangedBeacon.major.intValue, rangedBeacon.minor.intValue];
UPD: The most simple doesn't work too:
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"ANY region.beacons.minor = nil"];
UPD 2: Probably problem because of ANY+nil
According to this answer Core Data, NSPredicate, ANY key.path == nil ANY select only NOTNULL values.
Simply test for one of the properties of minor; for example:
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"region.beacons.minor.length = 0"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"region.beacons.minor.stringValue = nil"];
EDIT I recognized, that you should remove the ANY
If minor is nil, any call would return in nil as well, or 0 for numeric types.
For one thing, I notice you're using the assignment operator = instead of equality == while comparing with nil.
Also, try comparing with the Singleton NSNull instance [NSNull null].

NSPredicate nested dictionary dynamic key

I am using core data to fetch a list of objects. These objects have a property named 'categories'. This categories property is a NSDictionary constructed from json like :
#{#"A":#YES, #"B":#NO, #"C":#YES}
I want to get all core data objects which category is true for a given category key.
I tried :
NSString *categoryKey = #"A";
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"categories.%K == YES", categoryKey]];
// or
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.categories.%# == YES", categoryKey]];
// or
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"categories[%#] == YES", categoryKey];
// Throws exception : Unsupported function expression categories["A"]
// or
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"categories[%K] == YES", categoryKey];
// Throws exception : Unsupported function expression categories[A]
// or
NSString *categoryKeyPath = [NSString stringWithFormat:#"categories.%#", categoryKey];
NSPredicate *p = [NSPredicate predicateWithFormat:#"%K == YES", categoryKeyPath]];
But it always returns empty array when performing my fetch (of course I have some objects with categories[#"A"] = YES).
I think the problem comes from nested dictionary key path but I can't find a way to achieve this with one predicate.
Edit:
To clarify I would use
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
return [[evaluatedObject.categories objectForKey:categoryKey] boolValue];
}];
But predicateWithBlock: is not supported when fetching in core data.
If I understand correctly categories is a string attribute on your entity, which contains JSON data, and your managed objects parse this JSON so it can be read as a dictionary.
The problem is that the managed objects are not created before the fetch is performed. At that point, categories is just a string, and no key path will be able to extract the info you want from it. You will need to fetch all the objects so they can construct their dictionaries, then filter that collection. For large data sets, this may be slow.
Core Data is designed to be used by explicitly modelling the data; if you jam your own data structure inside a string, Core Data can’t help you. The more idiomatic design would be to have a Categories entity with a to-many/to-many relationship with the entity of your object. This makes it trivial to find all the objects in category A by fetching category A then following the relationship.
Try this
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.categories LIKE \"%#\":true", categoryKey]];

Core Data Predicate - Check if any element in array matches any element in another array

I'm trying to use a predicate to filter objects where an intersection exists between two arrays.
The NSManagedObject has an array(Of Strings) attribute named "transmissions". And there is another array(Of Strings) that will contain words to filter by, named "filters".
I'm not sure how to find if any elements in "transmissions" match any element in "filters".
I've tried
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ANY SELF.transmission in[c] %#",transmissions];
or
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ANY transmission in[c] %#",transmissions];
However, core data fetches no results where there should be some.
Try this.
NSPredicate *predicate = nil;
NSMutableArray *predicates = [NSMutableArray new];
for (NSString *transmission in transmissions) {
[predicates addObject:[NSPredicate predicateWithFormat:#"transmission == %#", transmission]];
}
if (predicates.count > 0)
predicate = [NSCompoundPredicate orPredicateWithSubpredicates:predicates];
// make fetch request using 'predicate'
You can use the keyword CONTAINS to check an object exists in a collection.
[NSPredicate predicateWithFormat:#"favouriteFilms CONTAINS %#", film]
I believe the same thing can be achieved with IN by switching the LHS and RHS of the predicate. I have only successfully implemented this functionality using CONTAINS however.

NSPredicate with SUBQUERY does not work

I need to sort my fetch request with selected people, but it doesn't return anything
I tried this code with coredata objects comparing
NSPredicate *peoplePredicate = [NSPredicate predicateWithFormat:#"SUBQUERY(classPeople, $p, $p IN %#).#count == %d", self.selectedPeople, [self.selectedPeople count]];
and this with nsnumber iD comparing
NSPredicate *peoplePredicate = [NSPredicate predicateWithFormat:#"SUBQUERY(classPeople, $p, $p.iD IN %#).#count == %d", self.selectedPeopleiD, [self.selectedPeopleiD count]];
I have entity class, which has relationship people. And I have viewcontroller where I can select some people in list, after selecting people objects are adding to array self.selectedPeople, so I need to fetch all objects of Class entity, which has selected people
thanks in advance
So, then your predicate should look like:
NSPredicate *peoplePredicate = [NSPredicate predicateWithFormat:#"ANY classPeople IN %#", self.selectedPeople];

Resources