Core Data pattern: how to efficiently update local info with changes from network?

主宰稳场 提交于 2019-11-29 21:08:51
Jesse Armand

Read "Implementing Find-or-Create Efficiently" in Core Data Programming Guide.

Basically you need to create an array of IDs or properties like names, or anything you have from the managed object entity.

Then you need to create a predicate that will filter the managed objects using this array.

[fetchRequest setPredicate:[NSPredicate predicateWithFormat: @"(objectID IN %@)", objectIDs]];

Of course "objectIDs" could be anything that you can use to identify. It doesn't have to be the NSManagedObjectID.

Then you could do one fetch request, and iterate the resulting fetched objects, to find duplicates. Add a new one if it doesn't exist.

You could probably take a lesson from email clients.

They work by first querying the server for a list of message IDs. Once the client has that list, it then compares against it's local data store to see if anything is different.

If there is a difference it takes one of a couple of actions. 1. If it exists on client, but not server AND we are IMAP, then delete locally. 2. If it exists on server, but not client, then download the rest of the message.

In your case, first query for all of the ids. Then send a follow up query to grab all of the data for the ones you don't already have.

If you have a situation where the record might exist locally, but might have been updated since the last download on the server, then your query should include the last updated date.

You should do one fetch across all the objects, but only fetch the server ID for the objects.

Use setPropertiesToFetch: with setResultType: set to NSDictionaryResultType.

It sounds like what you need is an NSSet of NSManagedObjectIDs which is loaded into memory or stored somewhere more quickly accessed than your persistent object store.

That way you can compare object IDs from the network with object IDs from your cache without having to perform a fetch request on a large data set.

Maybe add the ID to the cache from within -awakeFromInsert within your managed entity classes?

After fighting with this same issue for ages, i finally stumbled across this blog entry which totally resolved it (and is a reusable code block as a bonus!).

http://henrik.nyh.se/2007/01/importing-legacy-data-into-core-data-with-the-find-or-create-or-delete-pattern

While the code sample doesn't cover the network part; you simply need to load it into a NSDictionary. and then this deals with the syncing of the local Core Data context.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!