Does AFIncrementalStore need an NSMainQueueConcurrencyType context?

228 Views Asked by At

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.

1

There are 1 best solutions below

0
On

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