I have a Core Data entity named RSSItem
with a Date attribute named publicationDate
.
Is there a way to create a predicate for a NSFetchRequest
that would include all entities with a publication date in the last 24 hours?
I have tried this:
NSString* expression = @"publicationDate.timeIntervalSinceNow >= -86400";
return [NSPredicate predicateWithFormat:expression];
But that yields a nil
predicate, thus matching everything.
I would like to have a live predicate that change over time. Therefor a predicate with a NSDate
instance is not possible, since it defines an immutable single point in time, not a relative time such as the last 24 hours.
I think this should work:
[NSPredicate predicateWithFormat:@"publicationDate >= %@", [NSDate dateWithTimeIntervalSinceNow:-86400];
Update
You could try an alternate approach to get the live predicate to work. I think that you have to update the attribute(s) for an entity that are used in a predicate to trigger a filtering anyway so even if your proposed predicate was possible you would still have to loop through all items and fake an update for publicationDate
.
What you could try is add a bool attribute shouldDisplay
to RSSItem
and a method `updateShouldDisplay'
- (void)updateShouldDisplay {
self.shouldDisplay = [NSNumber numberWithBool:[self.publicationDate compare:[NSDate dateWithTimeIntervalSinceNow:-86400]] == NSOrderedDescending];
}
Then whenever you are refreshing the RSS feed you loop through all entities and call updateShouldDisplay
. You probably have to call updateShouldDisplay
from awakeFromFetch
as well.
And just to be complete the predicate would look like:
[NSPredicate predicateWithFormat:@"shouldDisplay == YES"]
I'm not 100% on this but I think you can't use transient properties in an NSPredicate which means you have to store shouldDisplay
.
Relative date is not a problem. You don't need the predicate to change. The 'last 24 hour' boundary is a fixed point in time relative to the current time. Create an
NSDate
and stick it in the predicate (like in Robert's answer above)For "live-ness", you could use a fetched property with the above predicate, putting the cutoff date/time in the userInfo dictionary. The results are cached by CoreData (because true live properties would cause a DB query each time, and could be expensive) so you need to call
NSManagedObjectContext refreshObject:
to update the data (say, whenever you're finished inserting a bunch of newRSSItem
s after a refresh).
精彩评论