How to observe changes on single instance of NSManagedObject

Michał Zaborowski
inspace labs
Published in
2 min readMay 11, 2016

In this post I will describe how to observe changes on single NSManagedObject instance. Motivation to wrote this article was my friend, who asked me:

“How do you observe changes on single object in CoreData? I know that there is NSFetchedResultsController but is it worth to observe only one object with it?!”

Of course it is possible to use NSFetchedResultsController but is was created for different things, if you read documentation you can find this:

“You use a fetched results controller to efficiently manage the results returned from a Core Data fetch request to provide data for a UITableView object. (…) While table views can be used in several ways, fetched results controllers are primarily intended to assist you with a master list view.

My answer was — don’t do it in this way. The most efficient way to do it is to observe NSManagedObjectContextObjectsDidChangeNotification. This notification is posted when values of properties for managed objects in context are changed. The userInfo dictionary contains the following keys: NSInsertedObjectsKey, NSUpdatedObjectsKey, and NSDeletedObjectsKey, NSRefreshedObjectsKey. If are already familiar with this, you can take a look on our wrapper which can save you from writing boilerplate code. I made gist with source code which you can find below the article and also here. This is how the interface for our observer look like:

It is very easy to use, all you need is to create instance of CoreDataContextObserver and pass context which you want to observe:

let context = NSManagedObjectContext.defaultContext
let observer = CoreDataContextObserver(context: context)

Next, you need to pass NSManagedObject instance which you will observe, and if something have changed you will get information about it in completion handler:

observer.observeObject(journal, completionBlock: { object, state in
print(“CHANGED: \(object.changedValuesForCurrentEvent())\n”)
print(“state: \(state)”)
})

CoreDataContextObserver is not limited to only one object, you can observe many objects for different state, for example if you want to know about journal deletion, you will observe .Deleted state:

observer.observeObject(journal, state: .Deleted, completionBlock: { object, state in
print(“OBJECT DELETED\n”)
})

In this way you can in clean way track all changes on NSManagedObject. I have created example project on our github where you can play with CoreDataContextObserver.

I want to mention is that if you are using

func mergeChangesFromContextDidSaveNotification(_ notification: NSNotification!)

then you will get changes in NSRefreshedObjectsKey. So, if you want to subscribe to this event using our observer you will use:

observer.observeObject(journal, state: .Refreshed, completionBlock: { object, state in
print(“OBJECT REFRESHED”)
})

If you found these resources helpful or you’re an awesome person hit the 💚. Here you will find example project and below you will find full source code:

--

--

Michał Zaborowski
inspace labs

iOS Developer, creator of Open-Source MZFormSheetController. Founder at @inspace_io