I am currently developing an application that uses Core Data to store data. The application synchronizes its content with a web server by downloading and parsing a huge XML file (about 40000 entries). The application allows the user to search data and modify it (CRUD). The fetch operations are too heavy, that is why i decided to use the following pattern :
"One managed object context for the main thread (NSMainQueueConcurrencyType) in order to refresh user interface. The heavy fetching and updates are done through multiple background managed object contexts (NSPrivateQueueConcurrencyType). No use of children contexts".
I fetch some objects into an array (let us say array of "users"), then i try to update or delete one "user" (the object "user" is obtained from the populated array)in a background context and finally i save that context.
I am listening to NSManagedObjectContextDidSaveNotification and merge any modifications with my main thread managed object context.
Every thing works fine except when i relaunch my application i realize that none of the modifications has been saved.
Here is some code to explain the used pattern
Main managed object context :
-(NSManagedObjectContext *)mainManagedObjectContext { if (_mainManagedObjectContext != nil) { return _mainManagedObjectContext; } NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; _mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; [_mainManagedObjectContext setPersistentStoreCoordinator:coordinator]; return _mainManagedObjectContext;}
Background managed object context :
-(NSManagedObjectContext *)newManagedObjectContext { NSManagedObjectContext *newContext; NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; newContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; [newContext performBlockAndWait:^{ [newContext setPersistentStoreCoordinator:coordinator]; }]; return newContext;}
Update a record :
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ FootBallCoach *coach = [_coaches objectAtIndex:indexPath.row]; coach.firstName = [NSString stringWithFormat:@"Coach %i",indexPath.row]; NSManagedObjectContext *context = [[SDCoreDataController sharedInstance] newManagedObjectContext]; [context performBlock:^{ NSError *error; [context save:&error]; if (error) { NSLog(@"ERROR SAVING : %@",error.localizedDescription); } dispatch_async(dispatch_get_main_queue(), ^{ [self refreshCoaches:nil]; }); }];}
Am i missing any thing ? should i save my main managed object context after saving the background context ?