NSFetchedResultsController múltiples entidades para UITableView

Tengo dos entidades, una llamada Post y una llamada Usuario. Publicar << —-> Usuario es la relación en los datos centrales. Estoy usando un NSFetchedResultsController para get todos los loggings de publicación en mi stack de datos centrales y luego mostrarlos en un UITableView. Cada celda tiene una image y esa image corresponde a un User.profilePicture.

Al inicializar no descargo la image del perfil del server, solo descargo cuando se desplaza por esa celda (carga perezosa). Una vez que lo descargué, guardé la image descargada en el User.profilePicture correspondiente en la stack de datos del núcleo.

¿Hay alguna forma de llamar a controllerDidChangeContent cuando actualizo la entidad de Usuario ?? Mi comprensión actual es que mi NSFetchedResultsController solo puede seguir a la entidad Post, ya que eso es lo que inicialmente lo programé y no puedo recorrer y monitorear las actualizaciones en una relación, ¿es cierto?

Lamentablemente, solo conozco una solución UGLY para este problema.

En su file .m de User implementa setProfilePicture: así:

 //NOT TESTED IN A MULTITHREADED ENV - (void) setProfilePicture:(NSData *)data { [self willChangeValueForKey:@"profilePicture"]; [self setPrimitiveValue:data forKey:@"profilePicture"]; [self.posts enumerateObjectsUsingBlock:^(Post* p, BOOL *stop) { [p willChangeValueForKey:@"user"]; [p didChangeValueForKey:@"user"]; }]; [self didChangeValueForKey:@"profilePicture"]; } 

Esto notificará al FRC que el elemento Publicar tiene cambios.

Puede encontrar información adicional aquí

Editar:

Para search los datos en el acceso, puede agregar esto a su User .m:

 //UNTESTED + (void) mergeToMain:(NSNotification*)notification { AppDelegate* appDel = (AppDelegate*)[[UIApplication shanetworkingApplication] delegate]; [appDel.managedObjectContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) withObject:notification waitUntilDone:YES]; } - (NSData*)_profilePicture { return [self primitiveValueForKey:@"profilePicture"]; } - (NSData*) profilePicture { [self willAccessValueForKey:@"profilePicture"]; NSData* picData = [self primitiveValueForKey:@"profilePicture"]; if (!name) { __block NSManagedObjectID* objectID = self.objectID; //This solves the multiple downloads per item by using a single queue //for all profile pictures download. //There are more concurrent ways to accomplish that dispatch_async(downloadSerialQueue, ^{ //define some serial queue for assuring you down download multiple times the same object NSError* error = nil; AppDelegate* appDel = (AppDelegate*)[[UIApplication shanetworkingApplication] delegate]; NSManagedObjectContext* context = [[NSManagedObjectContext alloc] init]; [context setPersistentStoreCoordinator:appDel.persistentStoreCoordinator]; [context setUndoManager:nil]; User* user = (User*)[context existingObjectWithID:objectID error:&error]; if (user && [user _profilePicture] == nil) { NSData *data = //[method to retrieve data from server]; if (data) { if (user) { user.profilePicture = data; } else { NSLog(@"ERROR:: error fetching user: %@",error); return; } [[NSNotificationCenter defaultCenter] addObserver:[self class] selector:@selector(mergeToMain:) name:NSManagedObjectContextDidSaveNotification object:context]; [context save:&error]; [[NSNotificationCenter defaultCenter] removeObserver:[self class] name:NSManagedObjectContextDidSaveNotification object:context]; } } }); } [self didAccessValueForKey:@"profilePicture"]; return picData; } 

Creo que este problema se puede resolver sin NSFetchedResultsController involucrado.

  1. use SDWebImage , SDWebImage puede cargar imágenes desde el server remoto de manera asíncrona, simplemente haga esto:

     [myImageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder.png"]]; 
  2. use KVO, agregue un observador a la entidad del Usuario y actualice la vista correspondiente de la image en consecuencia. Pero el código para KVO es bastante complejo, ReactiveCocoa puede simplificarlo:

     [RACAble(user.profilePicture) subscribeNext:^(UIImage *image) { [myImageView setImage:image]; }];