2

I've been working on incorporating AFIncrementalStore into our app following the example code in the repository that uses an SQLite backing store. All the examples use a singleton managedObjectContext with an NSMainQueueConcurrencyType.

+ (NSManagedObjectContext *)managedObjectContext {
    static NSManagedObjectContext *_managedObjectContext = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{

        NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
        if (coordinator != nil) {
            _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
            [_managedObjectContext setPersistentStoreCoordinator:coordinator];
        }
    });

    return _managedObjectContext;
}

Using this moc, I'm able to perform a fetch, see it get pulled from the network, and stored in the sqlite backing store. I tried changing it to use the NSPrivateQueueConcurrencyType, and while I would see the network request, nothing was ever saved to the SQLite backing store. However, if I leave this moc with main queue concurrency, and then create a child from it, and use that moc, then everything saves fine.

+ (User *)user
{
    // grab a user if we already have one
    NSManagedObjectContext *managedObjectContext = [VigilCoreDatabase managedObjectContext];
    NSManagedObjectContext *tmpContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    tmpContext.parentContext = managedObjectContext;

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    fetchRequest.fetchLimit = 1;
    [fetchRequest setAffectedStores:@[ ]];

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"User" inManagedObjectContext:tmpContext];
    [fetchRequest setEntity:entity];

    __block User *user = nil;
    [tmpContext performBlockAndWait:^{
        NSError *error = nil;
        NSArray *fetchedObjects = [tmpContext executeFetchRequest:fetchRequest error:&error];
        if (fetchedObjects == nil) {
            NSLog(@"error");
        }
        if(fetchedObjects.count > 0) {
            user = fetchedObjects[0];
        }
    }];
    return user;
}

I wanted to figure out if I was missing something in my understanding. I can't seem to find any examples that don't use a moc with main queue concurrency as the parent context (with the backing store using a private queue context), but at the same time can't find any documentation explaining whether this is required, or whether I need to do something to push changes to the parent manually when using a private queue context vs. having a main queue context in the stack.

sbonami
  • 1,892
  • 17
  • 33
Tim Ritchey
  • 171
  • 1
  • 9

1 Answers1

0

At this time AFIncrementalStore suffers from a bug. I asked an SO question about another IncrementalStore (it utilizes the same code) and the response leads me to believe AFIS requires NSMainQueueConcurrencyType

Community
  • 1
  • 1
sbonami
  • 1,892
  • 17
  • 33