Last active
September 4, 2018 15:34
-
-
Save manmal/1702221a478978668bd9e3fed5e2653e to your computer and use it in GitHub Desktop.
CoreStore + Ensembles - Merge data from ensembles.io into CoreStore such that the mainContext (and its listeners) notice changes to previously unregistered objects
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// mark - CDEPersistentStoreEnsembleDelegate | |
public func persistentStoreEnsemble(_ ensemble: CDEPersistentStoreEnsemble, didSaveMergeChangesWith notification: Notification) { | |
func mergeChanges(stack: DataStack) { | |
assert(Thread.isMainThread) | |
let mainContext = stack.internalContext() | |
// Store currently registered object IDs on the MAIN CONTEXT for later usage. | |
let registeredIDs = mainContext.registeredObjects.map { (object) -> NSManagedObjectID in | |
return object.objectID | |
} | |
// Start unsafe transaction (child context on main thread) | |
let transaction = stack.beginUnsafe() | |
let temporaryContext = transaction.internalContext() | |
// Merge changes into the transactional context. Objects that have not existed | |
// previously will be added to registeredObjects, but not to | |
// insertedObjects or updatedObjects. Therefore, we must refresh | |
// those later on. | |
temporaryContext.mergeChanges(fromContextDidSave: notification) | |
let _ = transaction.commitAndWait() | |
let updatedObjects = notification.userInfo?[NSUpdatedObjectsKey] as? Set<NSManagedObject> ?? Set<NSManagedObject>() | |
let createdObjects = notification.userInfo?[NSInsertedObjectsKey] as? Set<NSManagedObject> ?? Set<NSManagedObject>() | |
// ignore deleted objects - they are not a concern anymore if they were | |
// not registered before anyway. | |
let potentiallyUnregisteredObjects = updatedObjects.union(createdObjects) | |
let potentiallyUnregisteredObjectIDs = potentiallyUnregisteredObjects.map({ $0.objectID }) | |
// Refresh previously unregistered objects in the main context. | |
for unregisteredObjectID in potentiallyUnregisteredObjectIDs where !registeredIDs.contains(unregisteredObjectID) { | |
if let existingUnregisteredObject = try? mainContext.existingObject(with: unregisteredObjectID) { | |
mainContext.refresh(existingUnregisteredObject, mergeChanges: true) | |
} | |
} | |
} | |
if Thread.isMainThread { | |
mergeChanges(stack: db.stack) | |
} else { | |
// Switch to main thread | |
DispatchQueue.main.async { [weak self] in | |
if let strongSelf = self { | |
mergeChanges(stack: strongSelf.db.stack) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment