Skip to content

Instantly share code, notes, and snippets.

@kabouzeid
Last active September 9, 2020 17:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kabouzeid/019dd672f907d37750d5277b1f6df835 to your computer and use it in GitHub Desktop.
Save kabouzeid/019dd672f907d37750d5277b1f6df835 to your computer and use it in GitHub Desktop.
Simple extension to observe CoreData NSManagedObjects, behaves like the observe function in Realm.
//
// NSManagedObjectExtension.swift
//
// Created by Karim Abou Zeid on 10.06.18.
// Copyright © 2018 Karim Abou Zeid Software. All rights reserved.
//
import CoreData
extension NSManagedObject {
typealias OnChange = (ChangeType) -> ()
func observe(_ onChange: @escaping OnChange) -> NotificationToken {
return NotificationToken(object: self, onChange: onChange)
}
public enum ChangeType {
case change([String : Any])
case deleted
}
public class NotificationToken {
let onChange: OnChange
let object: NSManagedObject
init(object: NSManagedObject, onChange: @escaping OnChange) {
self.object = object
self.onChange = onChange
NotificationCenter.default.addObserver(self,
selector: #selector(contextObjectsDidChange(_:)),
name: Notification.Name.NSManagedObjectContextObjectsDidChange,
object: object.managedObjectContext)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
@objc
func contextObjectsDidChange(_ notification: Notification) {
if let objects = notification.userInfo?[NSInsertedObjectsKey] as? Set<NSManagedObject> {
if objects.contains(object) {
onChange(.change(object.changedValuesForCurrentEvent()))
}
}
if let objects = notification.userInfo?[NSUpdatedObjectsKey] as? Set<NSManagedObject> {
if objects.contains(object) {
onChange(.change(object.changedValuesForCurrentEvent()))
}
}
if let objects = notification.userInfo?[NSDeletedObjectsKey] as? Set<NSManagedObject> {
if objects.contains(object) {
onChange(.deleted)
}
}
if let objects = notification.userInfo?[NSRefreshedObjectsKey] as? Set<NSManagedObject> {
if objects.contains(object) {
onChange(.change(object.changedValuesForCurrentEvent()))
}
}
if let objects = notification.userInfo?[NSInvalidatedObjectsKey] as? Set<NSManagedObject> {
if objects.contains(object) {
onChange(.deleted)
}
}
if notification.userInfo?[NSInvalidatedAllObjectsKey] != nil {
onChange(.deleted)
}
}
}
}
@saroar
Copy link

saroar commented Sep 9, 2020

I try this code does work for me 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment