rokridi
rokridi

Reputation: 1675

Core data data not saved

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

  1. 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;
    

    }

  2. Background managed object context :

    -(NSManagedObjectContext *)newManagedObjectContext {
    
    NSManagedObjectContext *newContext;
    
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    
    newContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [newContext performBlockAndWait:^{
    
        [newContext setPersistentStoreCoordinator:coordinator];
    }];
    
    return newContext;
    

    }

  3. 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 ?

Upvotes: 0

Views: 1171

Answers (1)

eofster
eofster

Reputation: 2047

If your context is configured with a persistent store coordinator, then save should write data to the store. If your context is configured with another context as parent, then save will push the data to the parent. Only when the last parent, the one that is configured with persistent store coordinator is saved, is the data written to the store.

  1. Check that your background context is really configured with persistent store coordinator.
  2. Check the return value and possible error of the -save:.
  3. Make sure you work with your background context via -performBlock...: methods.

UPDATE

Each time you call your -newManagedObjectContext method, a new context is created. This context knows nothing about FootBallCoach object you’re updating. You need to save the same context FootBallCoach object belongs to.

Don’t forget that each object belongs to one and only one context.

Also make sure you hold a strong reference to a context whose objects you’re using.

Upvotes: 2

Related Questions