ios core-data transient sections

ios - Custom Core Data SectionNameKeyPath



core-data transient (2)

Soy nuevo en los datos básicos y estoy tratando de descubrir cómo crear una sectionNameKeyPath personalizadaNameKeyPath en mi NSFetchedResultsController . Tengo un objeto administrado con un atributo llamado acctPeriod . Es un NSString . Quiero crear secciones basadas en los primeros 4 caracteres de este campo. Los primeros 4 caracteres representan el año del período contable y no es necesario guardarlos.

He revisado este sitio y he visto publicaciones sobre atributos transitorios, pero parece que no puedo hacer que funcionen. Básicamente, quiero esto y luego asignar periodYear para mi sectionNameKeyPath .

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

Cualquier ayuda sería apreciada.

** ACTUALIZACIÓN: Utilizando la respuesta de Martin R., pude hacer que funcionara como esperaba.

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


Lo siguiente debería funcionar: Implemente el método periodYear (que se usará como "ruta de clave de nombre de sección") en una extensión de clase de su subclase de objeto gestionado:

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

Asegúrese de que acctPeriod se use como el primer (o único) descriptor de ordenación para la solicitud de búsqueda:

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

Use periodYear como sectionNameKeyPath para el controlador de resultados obtenido:

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

Y finalmente agregue el método predeterminado titleForHeaderInSection :

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

Alternativamente, puede definir periodYear como atributo transitorio del objeto gestionado. Tampoco se almacenará en la base de datos en ese caso, pero se puede implementar de forma tal que el valor se calcule a pedido y se almacene en caché.

El proyecto de muestra DateSectionTitles de Apple Developer Library demuestra cómo funciona esto.


Recomiendo que no se use una propiedad transitoria como sectionNameKeyPath ya que dará como resultado la falla de todos los objetos obtenidos por la solicitud de recuperación, de modo que la propiedad se pueda usar como la ruta de sección.
Es mejor definir una propiedad persistente del year y usarla como su sectionNameKeyPath .
establece FRC sectionNameKeyPath al year como sectionNameKeyPath :

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

para mostrar el nombre de la sección como un título en la tabla, implementar:

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