Skip to content

Instantly share code, notes, and snippets.

@kidap
Created September 12, 2018 14:28
Show Gist options
  • Save kidap/bfa4d274be028963111badec270b765f to your computer and use it in GitHub Desktop.
Save kidap/bfa4d274be028963111badec270b765f to your computer and use it in GitHub Desktop.
Context Observer
class ManagedObjectContextObserver {
// MARK: - Private properties
private let context: NSManagedObjectContext
private let notificationCenter: NotificationCenter
private let notification: NSNotification.Name
private let trackTypes: [NSManagedObject.Type]
private let queue: DispatchQueue
private var observers: [NSObjectProtocol] = []
// MARK: - Initializers
init(context: NSManagedObjectContext,
trackTypes: [NSManagedObject.Type],
notification: NSNotification.Name,
notificationCenter: NotificationCenter = NotificationCenter.default,
queue: DispatchQueue) {
self.context = context
self.trackTypes = trackTypes
self.notificationCenter = notificationCenter
self.queue = queue
self.notification = notification
}
deinit {
observers.removeAll()
notificationCenter.removeObserver(self, name: notification, object: context)
}
// MARK: - Public methods
func observeChanges(completion: @escaping (([AnyHashable: Any]?) -> Void)) {
let observer = notificationCenter.addObserver(forName: notification, object: context, queue: nil) { [weak self] notification in
self?.queue.async {
var hasChanges = false
let objectsKeys = [ NSInsertedObjectsKey,
NSUpdatedObjectsKey,
NSDeletedObjectsKey,
NSRefreshedObjectsKey,
NSInvalidatedObjectsKey]
for objectsKey in objectsKeys {
if let objects = notification.userInfo?[objectsKey] as? Set<NSManagedObject> {
hasChanges = self?.doesContainTrackedType(objects) ?? false
if hasChanges {
break
}
}
}
if hasChanges {
completion(notification.userInfo)
}
}
}
observers.append(observer)
}
}
private extension ManagedObjectContextObserver {
func doesContainTrackedType(_ objects: Set<NSManagedObject>) -> Bool {
let filteredObjects = objects.filter { object in
trackTypes.contains(where: { object.isKind(of: $0) })
}
return filteredObjects.count > 0
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment