Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sync data from web service with Core Data?

I'm trying to sync my data from a web service in a simple way. I download my data using AFNetworking, and using a unique identifier on each object, I want to either insert, delete or update that data.

The problem is that with Core Data you have to actually insert objects in the NSObjectManagedContext to instantiate NSManagedObjects. Like this:

MyModel *model = (MyModel *)[NSEntityDescription insertNewObjectForEntityForName:@"MyModel" inManagedObjectContext:moc];
model.value = [jsonDict objectForKey:@"value"];

So when I get the data from the web service, I insert them right away in Core Data. So there's no real syncing going on: I just delete everything beforehand and then insert what's being returned from my web service.

I guess there's a better way of doing this, but I don't know how. Any help?

like image 688
Michael Eilers Smith Avatar asked Jan 17 '14 20:01

Michael Eilers Smith


1 Answers

You are running into the classic insert/update/delete paradigm.

The answer is, it depends. If you get a chunk of json data then you can use KVC to extract the unique ids from that chunk and do a fetch against your context to find out what exists already. From there it is a simple loop over the chunk of data, inserting and updating as appropriate.

If you do not get the data in a nice chunk like that then you will probably need to do a fetch for each record to determine if it is an insert or update. That is far more expensive and should be avoided. Batch fetching before hand is recommended.

Deleting is just about as expensive as fetching/updating since you need to fetch the objects to delete them anyway so you might as well handle updating properly instead.

Update

Yes there is an efficient way of building the dictionary out of the Core Data objects. Once you get your array of existing objects back from Core Data, you can turn it into a dictionary with:

NSArray *array = ...; //Results from Core Data fetch
NSDictionary *objectMap = [NSDictionary dictionaryWithObjects:array forKeys:[array valueForKey:@"identifier"]];

This assumes that you have an attribute called identifier in your Core Data entity. Change the name as appropriate.

With that one line of code you now have all of your existing objects in a NSDictionary that you can then look up against as you walk the JSON.

like image 110
Marcus S. Zarra Avatar answered Sep 20 '22 13:09

Marcus S. Zarra