Efficient way to update table section headers using Core Data entities?
Im using a NSFetchedResultsController for my UITableView which displays a bunch of events im storing in core data.
What i am trying to do is group the table by relative date (ie Today, Tomorrow, This Week, etc..). Each event has a start date and i tried creating a transient property in the event entity called sectionIdentifier which converts开发者_C百科 the date into a relative date as mentioned above like so:
- (NSString*)sectionIdentifier
{
[self willAccessValueForKey:@"sectionIdentifier"];
NSString *tmp = [self primitiveSectionIdentifier];
[self didAccessValueForKey:@"sectionIdentifier"];
if (!tmp)
{
tmp = [Utility formattedDateRelativeToNow:self.startTime];
[self setPrimitiveSectionIdentifier:tmp];
}
return tmp;
}
The problem is that it obviously only does this once and doesn't update itself unless the date is changed which i dont really expect. I have thought of overriding the getStartDate accessor to update the sectionIdentifier although this seems a little heavy handed and inefficient as it would perform this update every time i access that property
Any ideas?
The best method for doing this is rather counterintuitive. Instead of changing the fetched results controller or anything in Core Data, you extend NSDate with a category to have a keyname/method that returns a value based on the appropriate date calculation. You then include the keyname/method in the fetched results controller sectionNameKeyPath
.
See this previous answer for an example of how to extend NSDate with keyname/methods like today, yesterday, tomorrow etc.
To use this, you would just take on the method to a date attribute of the entity the fetched results controller fetches like so:
NSFetchedResultsController *frc=[[NSFetchedResultsController alloc] initWithFetchRequest:aFetch
managedObjectContext:aMoc
sectionNameKeyPath:@"startdate.yesterday"
cacheName:nil];
... and the sections will appear automatically.
I think you will need to update you section headers as frequently as the smallest duration for which you are displaying a section (which seems to be one day). I would have proceeded in the following fashion-
1) Save the current time-stamp in applicationDidFinishLaunching
using NSUserDefaults
, etc.
2) Next time the application is launched, determine the difference between the current time-stamp & the one saved.
3) If the difference is more than your smallest duration (one day), regenerate your table, including section headers, as Today would have become Yesterday & Yesterday may have become last week.
HTH,
Akshay
精彩评论