0

For concurrency in coredata I am using parent-child MOC concept where parent context is of NSMainQueueConcurrencyType and child context is of NSPrivateQueueConcurrencyType and below is the code to

    - (NSManagedObjectContext *)managedObjectContext
     {
        if (managedObjectContext != nil) {
          return managedObjectContext;
        }

        NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
        if (coordinator != nil) {
            managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];// DONE to avoid crash when the app auto logs out
        managedObjectContext.persistentStoreCoordinator = coordinator;

        }
        return managedObjectContext;
    }

    -(NSManagedObjectContext *)getPrivateMOC
    {
        NSManagedObjectContext *private = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
        [private setParentContext:[self managedObjectContext]];

        return private;
    }

    -(void)storeCustomerData:(NSArray *)custData
     {
         NSManagedObjectContext *currentbgContext = [self getPrivateMOC];

[currentbgContext performBlock:^{



    for (NSDictionary *jsonObject in custData) {


        CustomerEntity *custEntity = [NSEntityDescription insertNewObjectForEntityForName:@"CustomerEntity" inManagedObjectContext:currentbgContext];

        custEntity.fname   = [jsonObject field:@"fname"];
        custEntity.lname  = [jsonObject field:@"lname"];


    }

    NSError *error = nil;
    if (![currentbgContext save:&error]) {
        NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]);
        //abort();
    }

}];

}

If I use parent context in method storeCustomerData it works but using child context getPrivateMOC() doesn't.

Please let me know if I am missing anything

koen
  • 5,383
  • 7
  • 50
  • 89
Praful Kadam
  • 372
  • 6
  • 22
  • Check this answer http://stackoverflow.com/questions/12271464/how-do-i-create-a-child-nsmanagedobjectcontext – LoVo Jun 28 '16 at 11:45

1 Answers1

0

I guess I understood your problem, Please try the below code

// Used to propegate saves to the persistent store (disk) without blocking the UI
- (NSManagedObjectContext *)masterManagedObjectContext {
    if (_masterManagedObjectContext != nil) {
        return _masterManagedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        _masterManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
        _masterManagedObjectContext.retainsRegisteredObjects = YES; //TO-DO : Need update this later
        [_masterManagedObjectContext performBlockAndWait:^{
            [_masterManagedObjectContext setPersistentStoreCoordinator:coordinator];
//            [_masterManagedObjectContext setUndoManager:nil];

        }];

    }
    return _masterManagedObjectContext;
}

// Return the NSManagedObjectContext to be used in the background during sync
- (NSManagedObjectContext *)backgroundManagedObjectContext {
    if (_backgroundManagedObjectContext != nil) {
        return _backgroundManagedObjectContext;
    }

    NSManagedObjectContext *masterContext = [self masterManagedObjectContext];
    if (masterContext != nil) {
        _backgroundManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
        [_backgroundManagedObjectContext performBlockAndWait:^{
            [_backgroundManagedObjectContext setParentContext:masterContext];
        }];
    }

    return _backgroundManagedObjectContext;
}

// Return the NSManagedObjectContext to be used in the background during sync
- (NSManagedObjectContext *)newManagedObjectContext {
    NSManagedObjectContext *newContext = nil;
    NSManagedObjectContext *masterContext = [self masterManagedObjectContext];
    if (masterContext != nil) {
        newContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
        [newContext performBlockAndWait:^{
            [newContext setParentContext:masterContext];
        }];
    }

    return newContext;
}

- (void)saveMasterContext {
    [self.masterManagedObjectContext performBlockAndWait:^{
        NSError *error = nil;
        BOOL saved = [self.masterManagedObjectContext save:&error];
        if (!saved) {
            // do some real error handling
            //NSLog(@"Could not save master context due to %@", error);
        }
    }];
}

- (void)saveBackgroundContext {
    [self.backgroundManagedObjectContext performBlockAndWait:^{
        NSError *error = nil;
        BOOL saved = [self.backgroundManagedObjectContext save:&error];
        if (!saved) {
            // do some real error handling
            //NSLog(@"Could not save background context due to %@", error);
        }
    }];
}




static dispatch_queue_t coredata_background_save_queue;

dispatch_queue_t background_save_queue()
{
    if (coredata_background_save_queue == NULL)
    {
        coredata_background_save_queue = dispatch_queue_create("com.magicalpanda.coredata.backgroundsaves", 0);
    }
    return coredata_background_save_queue;
}

- (void)saveDataInBackgroundWithContext:(void(^)(NSManagedObjectContext *context))saveBlock
{
 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
  [self saveDataInContext:saveBlock];
 });
}

- (void)saveDataInContext:(void(^)(NSManagedObjectContext *context))saveBlock
{
 NSManagedObjectContext *context = [[EFCoreDataController sharedInstance] backgroundManagedObjectContext];
 [context setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
 [[self objectContext] setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];
// [[self objectContext] observeContext:context];      //step 3

// block(context);          //step 4
 if ([context hasChanges])        //step 5
 {
        NSError *e;
  [[self objectContext] save:&e];  //MagicalRecord will dump errors to the console with this save method
 }
}
koen
  • 5,383
  • 7
  • 50
  • 89
Nattudurai
  • 856
  • 7
  • 9