Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Core Data, NSPredicate and to-many key

I have a Core Data model in which a Task entity includes an optional to-many relationship excludedOccurrences. One of the properties of excludedOccurrences is start, which is an NSDate object. The ExcludedOccurrence entity has an inverse mandatory to-one relationship to the Task entity.

In order to fetch tasks for a specified day, I need to make sure that the specified day does not appear as the start property of any ExcludedOccurrence entity. One of the sub-predicates I am trying to use is therefore

NSPredicate *occurrenceIsNotExcludedPredicate = [NSPredicate predicateWithFormat: @"(ALL excludedOccurrences.start != %@))", today]; 

where today is a NSDate object for today including only the day, month and year components. All of the excluded occurrences start properties also include just the day, month and year components.

While this should fine, at least reading the documentation for Core Data and NSPredicate, I get the following error message:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unsupported predicate

If I use the equivalent predicate

NSPredicate *occurrenceIsNotExcludedPredicate = [NSPredicate predicateWithFormat: @"!(ANY excludedOccurrences.start == %@))", today]; 

no exception is thrown, however the code does not work as expected: the occurrence for today, which should not be excluded, is instead excluded.

I am not sure also how to test for the case excludedOccurrences == nil: the following predicate

NSPredicate *nilPredicate = [NSPredicate predicateWithFormat: @"(excludedOccurrences == nil)"]; 

causes at runtime the exception

to-many key not allowed here

However, since the excludedOccurrences relationship is optional, I also need to test if it is nil.

How do I deal with this? Thank you in advance.

like image 636
Massimo Cafaro Avatar asked Jul 22 '09 10:07

Massimo Cafaro


People also ask

What is an NSPredicate?

NSPredicate is a Foundation class that specifies how data should be fetched or filtered. Its query language, which is like a cross between a SQL WHERE clause and a regular expression, provides an expressive, natural language interface to define logical conditions on which a collection is searched.

What is NSPredicate in Objective C?

CONTAINS operator : It allows to filter objects with matching subset. NSPredicate *filterByName = [NSPredicate predicateWithFormat:@"self. title CONTAINS[cd] %@",@"Tom"]; LIKE : Its simple comparison filter.

How do you write NSPredicate in Swift?

In Swift, constructors skip the "blahWith…" part and just use the class name as a function and then go straight to the arguments, so [NSPredicate predicateWithFormat: …] would become NSPredicate(format: …) . (For another example, [NSArray arrayWithObject: …] would become NSArray(object: …) .


1 Answers

To test for an empty relationship you should compare the count of the to-many key to zero.

[NSPredicate predicateWithFormat:@"excludedOccurrences.@count == 0"]; 

As for your subpredicates, be aware that you can only have one of either the ALL or ANY modifiers in your final predicate, although you can use that modifier multiple times throughout the predicate.

Not OK: ANY foo.bar = 1 AND ALL foo.baz = 2
OK: ANY foo.bar = 1 AND !(ANY foo.baz != 2)

like image 155
Ashley Clark Avatar answered Oct 16 '22 22:10

Ashley Clark