Сортировка с помощью NSFetchedResultsController
Использование XCode 4.6, iOS6, CoreData, UITableViewController, NSFetchesResultsController
Я выяснил, как получить следующие даты в переменных NSDate:
todayDate
yesterdayDate
thisWeek
lastWeek
thisMonth
lastMonth
lastYear
Теперь я хотел бы использовать NSFetchedResultsController, чтобы поместить данные в разделы на основе данных указанных выше переменных. Я предполагаю, что мне нужно будет сравнить даты:
if ([date1 compare:date2] == NSOrderedDescending) {
NSLog(@"date1 is later than date2");
} else if ([date1 compare:date2] == NSOrderedAscending) {
NSLog(@"date1 is earlier than date2");
} else {
NSLog(@"dates are the same");
}
Существует вероятность того, что некоторые пользователи не будут иметь некоторые разделы. Итак, мне нужна помощь с тем, что добавить в следующем методе, чтобы определить количество разделов на основе fetchRequest:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
Мне также нужно знать, как разделить данные на ячейки numberOfRowsInSection:
и отобразить его в ячейках cellforRowAtIndexPath:
Некоторые примеры кода были бы хорошими! Благодарю.
РЕДАКТИРОВАТЬ
Я еще не интегрировал контроллер, но ниже приведен код для извлечения:
- (void) refreshTable {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Meeting" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"lastmoddate" ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[self.managedObjectContext executeFetchRequest:fetchRequest onSuccess:^(NSArray *results) {
[self.refreshControl endRefreshing];
self.objects = results;
[self.tableView reloadData];
} onFailure:^(NSError *error) {
[self.refreshControl endRefreshing];
NSLog(@"An error %@, %@", error, [error userInfo]);
}];
Вот как я получаю даты:
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *components = [cal components:( NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:[[NSDate alloc] init]];
[components setHour:-[components hour]];
[components setMinute:-[components minute]];
[components setSecond:-[components second]];
NSDate *today = [cal dateByAddingComponents:components toDate:[[NSDate alloc] init] options:0]; //This variable should now be pointing at a date object that is the start of today (midnight);
[components setHour:-24];
[components setMinute:0];
[components setSecond:0];
NSDate *yesterday = [cal dateByAddingComponents:components toDate: today options:0];
components = [cal components:NSWeekdayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:[[NSDate alloc] init]];
[components setDay:([components day] - ([components weekday] - 1))];
NSDate *thisWeek = [cal dateFromComponents:components];
[components setDay:([components day] - 7)];
NSDate *lastWeek = [cal dateFromComponents:components];
[components setDay:([components day] - ([components day] -1))];
NSDate *thisMonth = [cal dateFromComponents:components];
[components setMonth:([components month] - 1)];
NSDate *lastMonth = [cal dateFromComponents:components];
1 ответ
Это то, что я бы сделал. Создайте базовую модель данных и сущность "пользователь" в этой модели. Я предполагаю, что вы знаете, как это сделать, но если вы не просто комментируете и плохо объясняете. Затем просто создайте пользовательский класс для вашей сущности, как и для любой другой сущности, и присвойте ему атрибут NSDate lastmoddate, плюс я бы добавил атрибут creationDate, который будет равен точной дате и времени создания сущности, чтобы вы могли использовать это как идентификатор для каждого UserEntity. Вам также нужно будет иметь массив отдельных массивов для каждого раздела, который вы хотите создать в UITableView. Когда вы добавляете сущность пользователя в свою модель, задаете атрибуты, а затем, поскольку вы сказали, что у некоторых пользователей может быть не каждая переменная, задайте любую переменную, которая не должна быть равна нулю. Когда вы инициализируете свои массивы, просто добавьте пользовательские объекты, для которых соответствующие атрибуты установлены в значение. Наконец, когда вы реализуете -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView, все, что вам нужно сделать, это подсчитать массивы.
Вот как это должно выглядеть:
Я собираюсь вызвать сущность, которая представляет каждого пользователя 'UserEntity' (его класс NSManagedObject будет иметь то же имя).
Следующий код входит в заголовок того, какой класс вы собираетесь использовать для создания и извлечения сущностей - вероятно, это будет тот же класс, который вы используете для отображения UITableView.
@interface Class : UITableViewController {
NSManagedObjectContext *managedObjectContext;
NSMutableArray *arrayOfArrays;
}
@property (retain, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (retain, nonatomic) NSMutableArray *arrayOfArrays;
Следующий код входит в реализацию того, какой класс вы собираетесь использовать для создания и извлечения сущностей - вероятно, это будет тот же класс, который вы используете для отображения UITableView.
// для добавления UserEntity в модель (базовая база данных) и установки ее атрибутов
- (UserEntity *)addUserEntityToModel {
UserEntity *myEnt = (UserEntity *)[NSEntityDescription insertNewObjectForEntityForName:@"UserEntity" inManagedObjectContext:self.managedObjectContext];
myEnt.creationDate = [NSDate date];
myEnt. lastmoddate = ...; //replace the '...' with however you get your date
//add any other values to the appropriate attributes here, any attributes that do not //pertain to the UserEntity simply ignore - they are automatically set to default when they //are created.
NSError *error = nil;
if(!managedObjectContext)
NSLog(@"managedObejctContext problem at ...");
else if (![managedObjectContext save:&error]) {
NSLog(@"context not saved!");;
} else
NSLog(@"context successfully saved.");
}
// для получения UserEntity
- (NSMutableArray *)getFetchArray {
NSFetchRequest *request = [[NSFetchRequest alloc] init];
if(!managedObjectContext) {
NSLog(@"There is no managedObjectContext at getFetchArray");
}
NSEntityDescription *entity = [NSEntityDescription entityForName:@"UserEntity" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"creationDate" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
NSLog(@"mutableFetchResults array is nil");
}
[request release];
return mutableFetchResults;
}
// настройка arrayOfArrays
-(void)createArrayOfArrays {
NSMutableArray *fetchArray = [self getFetchArray];
NSMutableArray *todayDateArray = [[NSMutableArray alloc] init];
NSMutableArray *yesterdayDateArray = [[NSMutableArray alloc] init];
NSMutableArray *thisWeekArray = [[NSMutableArray alloc] init];
//... create an array for each section you want
for (UserEntity *ue in fetchArray) {
if(ue.lastmoddate) { //if the attribute is not nil
if(ue.lastmoddate isEqual todayDate)
[todayDateArray insertObject:ue atIndex:0];
else if (ue.lastmoddate isEqual yesterdayDate)
[yesterdayDateArray insertObject:ue atIndex:0];
// ... do this for every section array
}
}
arrayOfArrays = [[NSMutableArray alloc] initWithObjects:todayDateArray,yesterdayDateArray,...(the rest of the arrays created for each attribute), nil]
[todayDateArray release];
[yesterdayDateArray release];
// ... release all the arrays except arrayOfArrays and fetchArray
}
// настройка управляемого ObjectContext
- (id)init {
self = [super init];
if (self) {
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];//what ever //the name of your appDel is.
NSManagedObjectContext *context = [appDelegate managedObjectContext];
self.managedObjectContext = context;
[self createArrayofArrays];//this first creates the arrayOfArrays and will set it //equal to anything that's saved in the database. If you add an entity you will need to update //it.
}
return self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return arrayOfArrays.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [[arrayOfArrays objectAtIndex:section] count];
}
// затем отображаем ячейки в табличном представлении
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
UserEntity *ent = (UserEntity *)[[arrayOfArrays objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
cell.accessoryType = UITableViewCellAccessoryBasic;
if(ent.lastmoddate) { //if lastmoddate is not nil
cell.textLabel.text = ent. lastmoddate;
} else {
NSLog(@"lastmoddate is nil at tableView: cellForRowAtIndexPath");
}
NSLog(@"tableView: cellForRowAtIndexPath called.");
return cell;
}