Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 825
squarefrog Avatar asked Jan 01 '13 10:01

squarefrog


1 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.

like image 127
Lorenzo B Avatar answered Oct 13 '22 15:10

Lorenzo B