2009-08-11 2 views
2

В моей базовой модели данных у меня есть сущность, у которой есть атрибут даты, и, как следует из названия, я хотел бы сгруппировать эту сущность через (неделю) дней.Группа по будням с основными данными

Проблема заключается в том, что даты хранятся более или менее как временные метки, и я не знаю, как создать предикат, который может группировать/фильтровать мои объекты соответствующим образом.

Я выяснил, что мне, вероятно, придется делать выборку за каждый день, поэтому создан следующий метод. Код, который мне нужен, находится прямо посередине.

- (NSFetchedResultsController *)fetchedResultsController:(NSDate *)day { 
if(fetchedResultsController != nil) 
    return fetchedResultsController; 

// Create and Configure Request 
NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:managedObjectContext]; 
[request setEntity:entity]; 

// Predicate 
// pseudo code where i'm clueless is marked by "<" and ">" - start 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"DateAttribute BETWEEN <first second of day> AND <last second of day>"]; 
// or 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"<dayofmonth-month-year of DateAttribute> LIKE <dayofmonth-month-year of day>"]; 
[request setPredicate:predicate]; 
// pseudo code where i'm clueless is marked by "<" and ">" - end 

// Sort descriptors 
NSSortDescriptor *titleDescriptor = [[NSSortDescriptor alloc] initWithKey:sortDescriptorName ascending:YES]; 
NSArray *sortDescriptors = [NSArray arrayWithObject:titleDescriptor]; 
[request setSortDescriptors:sortDescriptors]; 

// create and init fetchResultsController 
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"]; 
self.fetchedResultsController = aFetchedResultsController; 
fetchedResultsController.delegate = self; 

//Memory 
[request release]; 
[titleDescriptor release]; 
[aFetchedResultsController release]; 

return fetchedResultsController; 

}

Я бы очень признателен за любую помощь. Спасибо

ответ

5

Если вы хотите группировать по будням, проще всего добавить к вашему объекту атрибут, например «день недели»; то вы передаете «weekday» в качестве аргумента sectionNameKeyPath при инициализации NSFetchedResultsController. В этом случае нет необходимости указывать предикат: вы автоматически получите разделы для будних дней.

Если вы хотите группировать по дням, вы передаете DateAttribute в качестве аргумента sectionNameKeyPath при инициализации NSFetchedResultsController. Опять же, нет необходимости указывать предикат: вы автоматически получите разделы для дней.

Что вы пытаетесь сделать в своем коде, отличается от того, что вы просили. В самом деле, вы не пытаетесь вернуть разделы (т.е. группировать по атрибуту): вместо этого вы пытаетесь вернуть один раздел для вашего tableView, содержащий объекты, описанные вашей сущностью, удовлетворяющие конкретному предикату, а именно те, чей DateAttribute падает (возможно,) в текущий день. Для достижения этой цели, вы можете использовать следующий код:

// start by retrieving day, weekday, month and year components for today 
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 
NSDateComponents *todayComponents = [gregorian components:(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:[NSDate date]]; 
NSInteger theDay = [todayComponents day]; 
NSInteger theMonth = [todayComponents month]; 
NSInteger theYear = [todayComponents year]; 

// now build a NSDate object for the input date using these components 
NSDateComponents *components = [[NSDateComponents alloc] init]; 
[components setDay:theDay]; 
[components setMonth:theMonth]; 
[components setYear:theYear]; 
NSDate *thisDate = [gregorian dateFromComponents:components]; 
[components release]; 


// now build a NSDate object for tomorrow 
NSDateComponents *offsetComponents = [[NSDateComponents alloc] init]; 
[offsetComponents setDay:1]; 
NSDate *nextDate = [gregorian dateByAddingComponents:offsetComponents toDate:thisDate options:0]; 
[offsetComponents release]; 

NSDateComponents *tomorrowComponents = [gregorian components:(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:nextDate]; 
NSInteger tomorrowDay = [tomorrowComponents day]; 
NSInteger tomorrowMonth = [tomorrowComponents month]; 
NSInteger tomorrowYear = [tomorrowComponents year]; 

[gregorian release]; 


// now build the predicate needed to fetch the information 
NSPredicate *predicate = [NSPredicate predicateWithFormat: @"DateAttribute < %@ && DateAttribute > %@", nextDate, thisDate]; 

Этот предикат будет извлекать точно все объекты, у которых DateAttribute падает в течение текущего дня. Надеюсь это поможет.

+0

благодарит за ваш ответ! «Если вы хотите группировать по дням, вы передаете DateAttribute в качестве аргумента sectionNameKeyPath при инициализации NSFetchedResultsController. Опять же, нет необходимости указывать предикат: вы автоматически получите разделы для дней». было бы здорово, если бы это сработало, но при этом оно группируется по значению DateAttribute (который включает в себя время, например, «2009-07-02 20:51:27 -0400») p.s.: моя конечная цель - получить список будних дней, а при нажатии одной из них все объекты, связанные с этим днем, открываются в другом представлении таблицы. – gabtub

+0

Вы можете добиться этого, сохранив в своей сущности DateAttribute без времени, используя ту же технику, что и в моем примере кода: начиная с объекта NSDate (ваш DateAttribute), вы сначала извлекаете свои компоненты даты, а затем создаете другой объект NSDate, используя эти компоненты (поэтому он не содержит времени). Это последний объект NSDate, который вы храните в своей организации. Затем, восстанавливая объекты по их дневным работам, объясняется. –

+0

сначала я не хотел модифицировать модель данных, так как она была указана кем-то другим, но, к счастью, оказалось, что нам действительно не нужно хранить время и дату, а только дату, поэтому я использовал части вашего примера code = > работает спасибо большое! – gabtub

4

Hi @gabtub Я действительно рассматривал ваш вопрос, и у меня был вопрос такого же рода. Что я хотел сделать, так это разделить мой стол на разделы по дате, а не на метку времени, как вы упомянули. Так что я сделал добавлен новый метод в моем классе, который расширяет NSManagedObject (являющаяся сущность я выборка), что метод возвращает отформатированную дату, например:

- (NSString *)transactionDay{ 
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
[dateFormatter setDateStyle:NSDateFormatterMediumStyle]; 
return [dateFormatter stringFromDate:self.date];} 

затем изменил мою fetchedResultController быть:

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"transactionDay" cacheName:nil]; 

И все работает как шарм.

Проверьте ссылку, чтобы увидеть более подробную информацию. http://www.IPHONE4GAPP.NET/superdb-core-data-app-with-sections.html

+0

интересно, спасибо! – gabtub

+0

не забудьте выпустить dateFormatter. –

Смежные вопросы