Skip to content

Instantly share code, notes, and snippets.

@manmal
Last active September 4, 2018 15:34
Show Gist options
  • Save manmal/1702221a478978668bd9e3fed5e2653e to your computer and use it in GitHub Desktop.
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
// 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