What is the most efficient way to sync Core Data with JSON API

What would be the best way to sync my Core Data schema with a remote API serving JSON? At the moment I'm looping through each dictionary in the JSON response checking Core Data to see if the API ID exists.

This works great, but all thats left to do now is delete any local objects that aren't on the server. Here is an example of my JSON data:

[
   {
      "id":1234,
      "name":"My first object",
      "description":"This is a long string with lots of information"
   },
   {
      "id":1235,
      "name":"My second object",
      "description":"This is a long string with lots of information"
   }
]

Currently the only way I can think of accomplishing this is something like the following:

NSArray *jsonData = // Convert json data to array using NSJSONSerialization
NSInteger fetchedCount = _fetchedResultsController.fetchedObjects.count;

if (fetchedCount != jsonData.count) {

    for (int i = 0; i < fetchedCount; i++) {

        NSManagedObject *object = [_fetchedResultsController objectAtIndexPath: [NSIndexPath indexPathForItem:i
                                                                                                    inSection:0]];
        NSNumber *idNumber = object.apiID;

        BOOL shouldDelete = YES;

        for (NSDictionary *jsonDict in jsonData) {
            if ([jsonDict  objectForKey:@"id"] == idNumber) {
                shouldDelete = NO;
            }
        }

        if (shouldDelete) {

            // Delete object.
        }            
    }
}

I think that will be massively inefficient if the JSON array contains a lot of objects.

Answers


This could be ok, but I think you should apply the Find-or-Create pattern suggested in Apple doc. See here for a deep explanation Efficiently Importing Data (In particular see Implementing Find-or-Create Efficiently).

The overall idea is quite simple. Having two arrays of objects (the one you retrieve from Core Data and the one you retrieve from the service) that are ordered (by apiID and id resp.).

Obviously if there are a lot of data, I really suggest to perform operations in background. Remember that each thread needs to rely on its NSManagedObjectContext. Otherwise take advantage of new queue mechanism provided by iOS 5 API.

For the sake of completeness, I also suggest to read RayWenderlich tutorial How To Synchronize Core Data with a Web Service Part 1 and 2. It's very interesting.

Hope that helps.


Need Your Help

Scala on iOS using Avian

iphone ios scala jvm avian

There is a relatively-new lightweight JVM called Avian that can produce executables for iOS targets.

How to check "Allow Full Access" is granted since iOS 8.3 *from the container app*

ios objective-c ios8 ios8-extension ios-keyboard-extension

Prior to iOS 8.3, the way to check whether "Allow Full Access" was granted to a keyboard extension was through the following code in the container app: