tl;dr: type something here that won't crash if birthDate is nil:
I have an entity with a birthDate attribute and a fetched property with the following predicate, typed straight into the xcdatamodel file:
$FETCH_SOURCE.birthDate > birthDate
This happily returns a list of managed objects older than FETCH_SOURCE (the managed object where the fetch request is happening). But birthDate is optional, and if the birthDate for FETCH_SOURCE is nil...
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'can't use NULL on left hand side'
Note that it's fine if the attribute is nil for the object being compared. If I swap the arguments of the predicate:
birthDate < $FETCH_SOURCE.birthDate
...I get the same error. Trying to test it for nil:
(birthDate != nil AND birthDate < $FETCH_SOURCE.birthDate)
...gives...
'NSInvalidArgumentException', reason: 'illegal comparison with NULL'
Google hasn't heard of either of those errors so I'm thinking this is a recent state of affairs. The problem remains when it's a String being compared for equivalence, or whatever. Is there a way to fix this in the predicate so it correctly returns an empty list? Thanks.
Edit: To be clear, the question is whether it's possible to fix this crash in the predicate in the xcdatamodel file.
Update: The crash specifically happens when the Relationship fault for the NSFetchedPropertyDescription is triggered by trying to read anything about it, presumably because it doesn't attempt to run the predicate till then. It isn't nil however, and can be checked for nil without crashing.
I can't find any way to amend the predicate of the fetched property to avoid this error, but one workaround is to implement a custom getter for the olderHeroes
fetched property. This should return an empty array if the birthDate
is nil.
var olderHeroes: NSArray {
var array : NSArray
if self.birthDate == nil {
array = NSArray()
} else {
self.willAccessValueForKey("olderHeroes")
array = self.primitiveValueForKey("olderHeroes") as! NSArray
self.didAccessValueForKey("olderHeroes")
}
return array
}
Or in Objective-C:
-(NSArray *)olderHeroes {
NSArray *array;
if (self.birthDate == nil) {
array = [NSArray array];
} else {
[self willAccessValueForKey:@"olderHeroes"];
array = [self primitiveValueForKey:@"olderHeroes"];
[self didAccessValueForKey:@"olderHeroes"];
}
return array;
}
(These snippets go in the implementation file for the subclass of the FETCH_SOURCE entity).
If you want to have results containing either a nil value or it has to be greater or smaller than a certain date use the following:
((birthDate == nil) OR (birthDate < %@))
This works for me. I hope this is what you're asking. Had a bit of trouble understanding your question.
If you're asking to check a variable you're passing in the predicate, might the following work (untested):
(($FETCH_SOURCE.birthDate == nil && birthDate == nil) OR ($FETCH_SOURCE.birthDate < birthDate))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With