iphone objective-c ios core-data nsfetchedresultscontroller

iphone - Datos básicos: el objeto obtenido en el índice x tiene un nombre de sección fuera de orden ''xxxxxx. Los objetos deben estar ordenados por nombre de sección



objective-c ios (2)

Sé que no soy el primero en hacer esta pregunta pero estoy realmente perplejo ...

Básicamente tengo una pantalla con dos botones. Cada botón carga datos en una vista de tabla a continuación basada en una fecha. En la primera carga de la primera vista de tabla (el botón izquierdo está seleccionado de forma predeterminada) todo se muestra bien. Si hago clic en el botón derecho y aparece una vista de tabla en blanco, aparece el error.

El objeto obtenido en el índice x tiene un nombre de sección fuera de orden ''xxxxxx. Los objetos deben estar ordenados por nombre de sección.

Volviendo a la vista de tabla izquierda, los datos se han ido. Ambas vistas de tabla están vacías.

Cada vista de tabla tiene 2 secciones dependiendo de la hora de inicio del elemento. Si elimino las secciones los datos se muestran bien. Desafortunadamente, los necesito ... los datos se ordenan en las dos secciones de esta manera:

@interface NSString(agendaSessionKeyPath) @property (nonatomic, readonly) NSString *sessionSection; @end @implementation NSString(agendaSessionKeyPath) - (NSString *)sessionSection { int timeValue = [[self stringByReplacingOccurrencesOfString:@":" withString:@""] intValue]; //turns 11:00 to 1100 if (timeValue < 1200) return @"Morning"; else return @"Afternoon"; }

Solicitud de búsqueda

- (void)viewDidLoad { //other viewDidLoad stuff [self fetchSessions]; }

método que ordena los datos del botón izquierdo y derecho según la fecha:

- (void)fetchSessions { NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; [dateFormatter setDateFormat:@"yyyy-MM-dd"]; NSDate* date = nil; if (selected == 0) //left button is selected { date = [dateFormatter dateFromString:@"2012-09-26"]; } else if (selected == 1) //right button is selected { date = [dateFormatter dateFromString:@"2012-09-27"]; } NSPredicate *predicate = [NSPredicate predicateWithFormat:@"date == %@", date]; [self.fetchedResultsController.fetchRequest setPredicate:predicate]; NSError *error; if (![[self fetchedResultsController] performFetch:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); } }

controlador de resultados recuperados

- (NSFetchedResultsController *)fetchedResultsController { self.managedObjectContext = [[MATCDatabaseController sharedDatabaseController] managedObjectContext]; if (_fetchedResultsController != nil) { return _fetchedResultsController; } NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Session"]; NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES]; NSSortDescriptor *timeSort = [NSSortDescriptor sortDescriptorWithKey:@"timeValue" ascending:YES]; [fetchRequest setSortDescriptors:@[timeSort, sort]]; [fetchRequest setFetchBatchSize:20]; NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"startTime.sessionSection" cacheName:nil]; self.fetchedResultsController = theFetchedResultsController; [self.fetchedResultsController setDelegate:self]; return _fetchedResultsController; }

Cualquier ayuda es apreciada!


OK, eché un vistazo rápido.

Inicializa el FRC con:

[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"startTime.sessionSection" cacheName:nil];

lo que le indica que los títulos de sus secciones se obtendrán a través de la ruta de acceso startTime.sessionSection .

Ahora, el primer descriptor de clasificación de una solicitud de recuperación que se entrega a un FRC se utilizará para ordenar las secciones. El descriptor de clasificación que está proporcionando primero es para timeValue que no parece correcto.

Su primer descriptor de clasificación debe especificar una clasificación para los títulos de su sección. Cambia eso y puedes ser bueno para irte.

EDITAR

Gracias por la información muchachos. Aunque todavía estoy un poco perdido. ¿Quería decir que debería agregar un descriptor de clasificación en startTime.sessionSection antes de asignarlo a la secciónNameKeyPath? Lo intenté, pero todavía no tengo suerte. TimeValue y startTime.sessionSection están relacionados. ¿Podría ser eso? Paloma

Debe asegurarse de que el primer descriptor de clasificación ordenará correctamente sus datos según la sección. En tu caso, los tiempos se están convirtiendo en palabras. Su descriptor de clasificación inicial es para los tiempos, y cuando los datos se ordenan según el tiempo, las secciones no se ordenan correctamente, lo que está causando su error.

El primer descriptor de clasificación debe satisfacer los datos de la sección. Así que, inicialmente, lo intentaría ...

[fetchRequest setSortDescriptors:@[ [NSSortDescriptor sortDescriptorWithKey:@"startTime.sessionSection" ascending:NO], [NSSortDescriptor sortDescriptorWithKey:@"timeValue" ascending:YES], [NSSortDescriptor sortDescriptorWithKey:@"title" ascending:YES] ];

Tenga en cuenta que si tiene muchos datos, es posible que el mecanismo de su sección se ralentice. Si eso sucede, es posible que desee agregar los datos de esta sección a su base de datos.


También tengo un problema similar, tal vez alguien lo encuentre útil.

Obtuve transacciones financieras de DB y las dividí por mes.

DB tiene propiedad trDate, que es una fecha de transacción. Pero trMonth es una propiedad transitoria como:

- (NSString*)trMonth { NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"LLLL"]; [dateFormatter setLocale:[NSLocale currentLocale]]; return [dateFormatter stringFromDate:trDate]; }

Fue utilizado en FetchResultsController de esta manera:

... NSSortDescriptor *sortDate = [[NSSortDescriptor alloc] initWithKey:@"trDate" ascending:YES]; [fetchRequest setSortDescriptors:@[sortDate]]; NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"trMonth" cacheName:nil]; ...

Lo que funcionó bien en la producción, pero una vez que la aplicación comenzó a fallar, y después de descubrir el problema de raíz, descubrí que había dos transacciones para (por ejemplo) en julio: julio de 2014 y julio de 2015. 2014 <julio de 2015, pero mi método los consideró como el mismo mes. La solución se usó como nombres de sección, no solo el nombre del mes, sino también el año:

- (NSString*)trMonthYear { NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"LLLL yyyy"]; // added year also [dateFormatter setLocale:[NSLocale currentLocale]]; return [dateFormatter stringFromDate:trDate]; }