Core Data Sort By Date With FetchedResultsController into sections
Is there a way to group objects from a CoreData entity by date and use them to create multiple sections on a UITableView control?
Essentially, I need something equivalent to the following pseudo-SQL, where my_group_criteria() groups all tests by day:
SELECT * FROM tests GROUP BY my_group_criteria(date)
As an example, the query would group the following rows into 3 separate sections:
[test1 | 2013-03-18 15.30.22]
[test2 | 2013-03-18 14.30.22]
[test3 | 2013-03-18 13.30.22]
[test4 | 2013-03-17 18.30.22]
[test5 | 2013-03-17 19.30.22]
[test6 | 2013-03-15 20.30.22]
As already answered in 2, NSPredicate is not for grouping entities so this may not be the way to go.
Given this, how do I go about creating multiple sections in a UITableView based on some criteria similar to what SQL GROUP BY would do?
I would like to avoid accessing the SQL-lite database directly if at all possible.
Related question 1: NSPredicate: filtering objects by day of NSDate property
Related question 2: NSPredicate something equivalent of SQL's GROUP BY
You can modify the DateSectionTitles sample project from the Apple Developer Library according to you needs.
First, you have to modify the accessor function for the transient sectionIdentifier
property to create a section identifier based on year+month+day (instead of year+month only):
- (NSString *)sectionIdentifier {
// Create and cache the section identifier on demand.
[self willAccessValueForKey:@"sectionIdentifier"];
NSString *tmp = [self primitiveSectionIdentifier];
[self didAccessValueForKey:@"sectionIdentifier"];
if (!tmp) {
/*
Sections are organized by month and year. Create the section identifier
as a string representing the number (year * 10000 + month * 100 + day);
this way they will be correctly ordered chronologically regardless of
the actual name of the month.
*/
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit)
fromDate:[self timeStamp]];
tmp = [NSString stringWithFormat:@"%d", [components year] * 10000 + [components month] * 100 + [components day]];
[self setPrimitiveSectionIdentifier:tmp];
}
return tmp;
}
Second, the titleForHeaderInSection
delegate method must be changed, but the idea is the same: extract year, month and day from the section identifer, and create a header title string from that:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> theSection = [[fetchedResultsController sections] objectAtIndex:section];
NSInteger numericSection = [[theSection name] integerValue];
NSInteger year = numericSection / 10000;
NSInteger month = (numericSection / 100) % 100;
NSInteger day = numericSection % 100;
// Create header title YYYY-MM-DD (as an example):
NSString *titleString = [NSString stringWithFormat:@"%d-%d-%d", year, month, day];
return titleString;
}
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