2013-04-08 14 views
14

Jestem nowy w podstawowych danych i próbuję dowiedzieć się, jak utworzyć niestandardową sectionNameKeyPath w moim NSFetchedResultsController. Mam obiekt zarządzany z atrybutem o nazwie acctPeriod. Jest to NSString. Chcę utworzyć sekcje na podstawie pierwszych 4 znaków tego pola. Pierwsze 4 znaki oznaczają rok okresu rozliczeniowego i nie trzeba ich zapisywać.Niestandardowe dane podstawowe SectionNameKeyPath

Przeszedłem przez tę stronę i widziałem posty o przejściowych atrybutach, ale nie mogę ich zmusić do działania. Zasadniczo chcę tego, a następnie przypisać periodYear dla mojego sectionNameKeyPath.

@dynamic periodYear; 

-(NSString *)periodYear 
{ 
    return [self.acctPeriod substringToIndex:4]; 
} 

Każda pomoc zostanie doceniona.

** AKTUALIZACJA: Używając odpowiedzi Martina R., udało mi się uruchomić go zgodnie z oczekiwaniami.

- (NSFetchedResultsController *)fetchedResultsController 
{ 
if (_fetchedResultsController != nil) { 
    return _fetchedResultsController; 
} 

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 

// Edit the entity name as appropriate. 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Billing" inManagedObjectContext:self.managedObjectContext]; 
[fetchRequest setEntity:entity]; 

// Set the batch size to a suitable number. 
[fetchRequest setFetchBatchSize:20]; 

// Edit the sort key as appropriate. 
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"acctPeriod" ascending:NO]; 
NSArray *sortDescriptors = @[sortDescriptor]; 

//Predicate 
NSPredicate *pred = [NSPredicate predicateWithFormat:@"clients = %@", self.client]; 
NSLog(@"%@",pred); 

//[fetchRequest setResultType:NSDictionaryResultType]; 
//[fetchRequest setReturnsDistinctResults:YES]; 

[fetchRequest setPredicate:pred]; 
[fetchRequest setSortDescriptors:sortDescriptors]; 

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"periodYear" cacheName:nil]; 
aFetchedResultsController.delegate = self; 
self.fetchedResultsController = aFetchedResultsController; 

NSError *error = nil; 
if (![self.fetchedResultsController performFetch:&error]) 
{ 
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
    abort(); 
} 

return _fetchedResultsController; 
} 

Odpowiedz

26

Poniższy powinno działać: Wdrożenie metody periodYear (która będzie używana jako "ścieżka nazwy sekcji sekcji") w rozszerzeniu klasy podklasy zarządzanych obiektów:

@interface Event (AdditionalMethods) 
- (NSString *)periodYear; 
@end 

@implementation Event (AdditionalMethods) 
- (NSString *)periodYear { 
    return [self.acctPeriod substringToIndex:4]; 
} 
@end 

Upewnij się, że acctPeriod stosowany jest jako pierwszy (lub tylko) sortowania deskryptorze na życzenie zwrcania:

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"acctPeriod" ascending:YES]; 
NSArray *sortDescriptors = @[sortDescriptor]; 
[fetchRequest setSortDescriptors:sortDescriptors]; 

Zastosowanie periodYear jak sectionNameKeyPath na wyniki pobranego sterownika:

NSFetchedResultsController *_fetchedResultsController = [[NSFetchedResultsController alloc] 
        initWithFetchRequest:fetchRequest 
        managedObjectContext:self.managedObjectContext 
        sectionNameKeyPath:@"periodYear" 
           cacheName:nil]; 
_fetchedResultsController.delegate = self; 
self.fetchedResultsController = _fetchedResultsController; 

i wreszcie dodaj domyślną metodę titleForHeaderInSection:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section]; 
    return [sectionInfo name]; 
} 

Można także zdefiniować przejściowy atrybut periodYear jako zarządzanego obiektu. W takim przypadku nie będzie również przechowywany w bazie danych, ale można go zaimplementować w taki sposób, aby wartość była obliczana na żądanie i buforowana.

Przykładowy projekt z biblioteki programistów Apple demonstruje, jak to działa.

+0

OK, to działało świetnie. Próbowałem tego wcześniej, ale problemem jest to, że próbuję tylko załadować 1 z moich obiektów, acctPeriod i posortować go według okresuYear.Więc użyłem [fetchRequest setPropertiesToFetch: [NSArray arrayWithObjects: [entityProperties objectForKey: @ "acctPeriod"], nil]]; co wydaje się nie działać. Próbowałem umieścić periodYear jako entityProperty, ale wiem, że tak nie jest. Otrzymuję ten błąd: "Nieprawidłowy okres keypathYear przeszedł do setPropertiesToFetch:" Jakieś przemyślenia? – theDVUSone

+0

@theDVUSone: Jeśli użyjesz 'propertiesToFetch', prawdopodobnie będziesz musiał zdefiniować' periodYear' jako przejściowy atrybut i dodać go do 'propertiesToFetch'. Nie próbowałem tego, ale właśnie to zakładam. –

+0

Popełniłem błąd polegający na zadeklarowaniu @property, która zaimplementowała gettera. To rozwiązanie mniej więcej wskazywało, że powinna to być deklaracja metody. – JLust

8

odradzam przemijające własności jako sectionNameKeyPath jak będzie to skutkować faulting wszystkie przedmioty otrzymane przez żądanie zwrcania tak nieruchomość mogłaby zostać wykorzystana jako ścieżka przekroju.
Lepiej zdefiniuj stałą właściwość year i użyj jej jako swojego sectionNameKeyPath.
ustawić Ci FRC sectionNameKeyPath do year tak:

[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
            managedObjectContext:self.managedObjectContext 
             sectionNameKeyPath:@"year" 
               cacheName:nil/*your chioce*/]; 

aby wyświetlić nazwę sekcji jako tytuł w tabeli, wdrożenia:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 
{ 
    id<NSFetchedResultsSectionInfo> sec = [self.fetchedResultsController sections][section]; 
    return [sec name]; 
} 
Powiązane problemy