I've been reading some links and posts regarding using parent and child NSManagedObjectContext
in Core Data
, but the example scenarios I've found deal with simply editing the attributes of a certain object in the parent context, and then pushing changes to the parent context.
The scenario I need to handle is a bit complex and I'm not sure how to manage it:
I have a set of managed objects in the default context (the one that is provided in AppDelegate
in the main queue). My app periodically call web services to check if there are updates for those objects. I want to do perform these updates in a separated thread to avoid blocking de UI, so, when it's time to call de services to ask for updates, I do this:
let bundle = NSBundle.mainBundle()
let modelURL = bundle.URLForResource("MyApp", withExtension: "momd")
let model = NSManagedObjectModel(contentsOfURL: modelURL!)!
let psc = NSPersistentStoreCoordinator(managedObjectModel: model)
let privateContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType)
privateContext.persistentStoreCoordinator = psc
let documentsURL = CoreDataHelper.applicationDocumentsDirectory()
let storeURL = documentsURL.URLByAppendingPathComponent("MyApp.sqlite")
let options = [NSMigratePersistentStoresAutomaticallyOption: true]
var error: NSError? = nil
let store: NSPersistentStore? = psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: options, error: &error)
That is, I create a new context in a private queue and with its own new persistent store coordinator and persistent store.
Once I have my private context, I request the updates to services:
[privateContext performBlockAndWait: ^{
// Call services
// Create new objects in this private context with
// the data in services responses
}];
Everything ok at this point. I have an "old" set of objects in my main context, and a "new" set of objects in the private context. I need to replace the set of objects of the main context with the new set of objects in the private one. The issues here are:
- Some of the objects that are in main context could not exist anymore in the private context, so I'll need to delete them.
- There could be new objects in the private context that don't exist in the main context, I'll need to add them.
- There could be objects in the private context that also are in the main one, but need to update some of their attributes.
I don't know if parent/child contexts can handle this kind of updates, or they are only appropriate for letting users to edit certain objects. Here it is not the user who edits the objects, so I need to avoid blocking the UI, and furthermore I'm not just modifying objects information, but deleting and adding new objects if needed.
I have some questions regarding parent/child contexts:
- Can a child context be in a private queue and the parent context in the main queue?
- I've read somewhere something about setting a merge policy, but I didn't find examples of its use, maybe is not necessary to set a merge policy when usen parent/child contexts? When would they be set? Where can I find an example or tutorial?
- If I set my private context as child of the main context, and I save the child private context, will the objects in private context "replace" the objects in the main context as I want? (including deleting the objects that are no longer present in the private context and the new ones)... I mean... does the whole child context replace the whole parent context?
- Would it be better to save the private context without being a child of the main one, and then clearing and refetching all the new data in the main context?
I need help to understand how this works and which is the best way to manage my scenario.
Thanks in advance.
List item