Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Core Data background fetching via new NSPrivateQueueConcurrencyType

Tags:

core-data

ios5

Is it really so simple now in iOS5?

I used to perform a background fetch using this code in my AppDelegate:

dispatch_queue_t downloadQueue = dispatch_queue_create("DownloadQueue", NULL);
dispatch_async(downloadQueue, ^{
        self.myDownloadClass = [[MyDownloadClass alloc]initInManagedObjectContext:self.managedObjectContext];
        [self.myDownloadClass download];
    });

dispatch_release(downloadQueue);

My download class performs an NSURLConnection to fetch some XML data, uses NSXMLParser to parse the data, and then updates a complex schema in core data. I would always switch to the main thread to actually update the core data. Messy code, with lots of calls to dispatch_sync(dispatch_get_main_queue()....

My new code looks like this:

NSManagedObjectContext *child = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[child setParentContext:self.managedObjectContext];

[child performBlock:^{
    self.myDownloadClass = [[MyDownloadClass alloc]initInManagedObjectContext:child];
    [self.myDownloadClass download];
    }];

along with a small change to some other code in my AppDelegate to set the parent model object context type to NSMainQueueConcurrencyType:

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

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

It seems to work very well. The entire update process still runs in a separate thread, but I did not have to create a thread. Seems like magic.

Just remember if you want to commit your changes to the physical core data files, you have call save: on the parent context as well.

I didn't really ask a question here. I'm posting this so it helps others because everything I found when searching for the new iOS5 managed object context methods only gave high level details with no code examples And all the other searches for fetching core data in the background are old, sometimes very old, and discuss how to do it pre-iOS5.

like image 492
Paul Heller Avatar asked Nov 29 '11 02:11

Paul Heller


1 Answers

Yes - it is really that easy now (in iOS 5.0). For iOS 4 compatibility, the previous hurdles remain, but the documentation is not too bad on thread confinement. Maybe you should add this to a wiki section?

like image 102
Scott Corscadden Avatar answered Oct 29 '22 13:10

Scott Corscadden