2009-08-11 18 views
2

In meinem Kerndatenmodell habe ich eine Entität mit einem Datumsattribut, und wie der Titel vermuten lässt, möchte ich diese Entität nach (Woche) Tagen gruppieren.Gruppieren nach Wochentagen mit Kerndaten

Das Problem ist, die Daten werden mehr oder weniger als Zeitstempel gespeichert und ich weiß nicht, wie man ein Prädikat erstellt, das in der Lage ist, meine Entitäten angemessen zu gruppieren/filtern.

Ich habe herausgefunden, dass ich wahrscheinlich für jeden Tag holen müssen, so erstellt folgende Methode. Der Code, mit dem ich Hilfe brauche, ist genau in der Mitte.

- (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; 

}

Ich würde wirklich jede Hilfe dankbar. Danke

Antwort

5

Wenn Sie nach Wochentag gruppieren möchten, ist die einfachste Sache, ein Attribut wie "wochentag" zu Ihrer Entität hinzuzufügen; dann übergeben Sie "wochentag" als Argument sectionNameKeyPath, wenn NSFetchedResultsController initialisiert wird. In diesem Fall müssen Sie kein Prädikat angeben: Sie erhalten automatisch Abschnitte für die Wochentage.

Wenn Sie nach Tag gruppieren möchten, übergeben Sie DateAttribute als Argument sectionNameKeyPath, wenn NSFetchedResultsController initialisiert wird. Auch hier müssen Sie kein Prädikat angeben: Sie erhalten automatisch Abschnitte für die Tage.

Was Sie in Ihrem Code versuchen, unterscheidet sich von dem, was Sie gefragt haben. Tatsächlich versuchen Sie nicht, Abschnitte zurück zu bekommen (zB Gruppierung nach einem Attribut): Sie versuchen stattdessen, einen einzigen Abschnitt für Ihr tabletView zurück zu bekommen, der Objekte enthält, die von Ihrer Entität beschrieben werden, die ein spezifisches Prädikat erfüllt, nämlich diejenigen, deren DateAttribute fällt) am heutigen Tag. Um dies zu erreichen, können Sie den folgenden Code verwenden:

// 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]; 

Dieses Prädikat abruft genau alle Objekte, deren DateAttribute fällt in den aktuellen Tag. Hoffe das hilft.

+0

danke für Ihre umfassende Antwort! "Wenn Sie nach Tag gruppieren möchten, übergeben Sie DateAttribute als Argument sectionNameKeyPath, wenn Sie NSFetchedResultsController initialisieren. Auch hier müssen Sie kein Prädikat angeben: Sie erhalten automatisch Abschnitte für die Tage." wäre es toll, wenn das funktioniert hätte, aber wenn es so gemacht wird, gruppiert es sich nach dem Wert des DateAttribute (das die Zeit einschließt, z.B. "2009-07-02 20:51:27 - 0400") p.s.: Mein ultimatives Ziel ist es, eine Liste von Wochentagen zu erhalten, und wenn man auf einen von ihnen klickt, öffnen sich alle Entitäten, die mit diesem Tag verbunden sind, in einer anderen Tabellenansicht. – gabtub

+0

Sie können dies erreichen, indem Sie in Ihrer Entity das DateAttribute ohne die Zeit mit derselben Technik speichern, die ich in meinem Beispielcode gezeigt habe: Ausgehend von einem NSDate-Objekt (Ihrem DateAttribute) entpacken Sie zunächst seine Datumskomponenten und erstellen dann ein anderes NSDate-Objekt diese Komponenten (daher enthält es nicht die Zeit). Es ist dieses letzte NSDate-Objekt, das Sie in Ihrer Entität speichern. Dann funktioniert das Abrufen der Objekte auf der Grundlage ihres Tages wie erläutert. –

+0

Zuerst wollte ich das Datenmodell nicht ändern, da es von jemand anderem spezifiziert wurde, aber zum Glück stellte sich heraus, dass wir nicht Zeit und Datum speichern mussten, sondern nur Datum, also benutzte ich Teile Ihres Beispielcodes = > funktioniert vielen Dank! – gabtub

4

Hallo @gabtub Ich war tatsächlich auf Ihre Frage und ich hatte eine Frage der gleichen Art. Was ich tun wollte, war meine Tabelle in Abschnitte nach Datum und nicht Zeitstempel wie du erwähnt zu teilen. Also, was ich habe ist eine neue Methode in meiner Klasse hinzugefügt, die NSManagedObject erstreckt (das ist die Einheit i Abrufen ist), dass Methode gibt ein formatierte Datum als solche:

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

dann änderte meinen fetchedResultController zu sein:

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

Und alles hat wie ein Charme gearbeitet.

Überprüfen Sie den Link, um mehr Details zu sehen. http://www.IPHONE4GAPP.NET/superdb-core-data-app-with-sections.html

+0

interessant, danke! – gabtub

+0

Vergessen Sie nicht, den dateFormatter zu veröffentlichen. –