CoreData Notifications With Swift
After the series about CRUD operations, now it’s time to unveil the last Core Data beast: Notifications.
Introduction
As you may have noticed, I’ve written several articles about Core Data recently. I wanted to study this framework well to publish a new open source library, StorageKit. Then, I thought to share with the community my knowledge because I think it’s very important to know how to take advantage of all the Core Data features.
In this article, we’ll see how to use the notifications provided by Core Data.
Happy reading!
Notifications
Core data provides the possibility to observer different notifications which we receive when something changes in our Core Data environment.
Let’s see what notifications we can observer and how to use them:
NSManagedObjectContextObjectsDidChange
CoreData sends this notification when we perform any CRUD operations with a NSManagedObject
.
Note:
We don’t need to save the changes in the context to receive this notification. Once we perform a CRUD operation, we’ll receive this notification. For example, if we create a new object like this:
1 2
let test = Test(context: persistentContainer.viewContext) test.name = "Hello World"
1 2 3
we'll receive the notification even though we didn't save the context.
Since we receive this notification only when we change manually a
NSManagedObject
, we don’t trigger it if we executeNSBatchUpdateRequest
/NSBatchDeleteRequest
.
NSManagedObjectContextWillSave
CoreData sends this notification when we are going to save a context with the method save
of NSManagedObjectContext
. It may be useful if we have to perform some actions before keeping the persistence of our changes.
NSManagedObjectContextDidSave
This notification is very similar to NSManagedObjectContextWillSave
. The only difference is that CoreData sends it after saving the context.
Usage
We can observer these notifications adding an observer to NotificationCenter
like this:
|
|
And the selectors are like these:
|
|
The object Notification
stores also the context where we changed the NSManagedObject
(for NSManagedObjectContextObjectsDidChange
), where we are going to save (for NSManagedObjectContextWillSave
) and where we saved (NSManagedObjectContextDidSave
).
We can read the context like this:
|
|
Keys
The notifications are just half of the whole story. Inside the userInfo
of the Notification
object, Core Data provides also some Set
s with the information of what has been changed.
Let’s see the list of keys which we can use to retrieve the data changed:
NSInsertedObjectsKey
This is the key for a Set
which contains all the NSManagedObject
s inserted.
If we observe NSManagedObjectContextObjectsDidChange
, the Set
of this key contains the object which we create like in this example:
|
|
NSUpdatedObjectsKey
This is the key for a Set
which contains all the NSManagedObject
s updated.
NSDeletedObjectsKey
This is the key for a Set
which contains all the NSManagedObject
s deleted.
NSRefreshedObjectsKey
This is the key for a Set
which contains all the NSManagedObject
s refreshed.
Refreshing objects
When we perform any CRUD operations in a NSManagedObject
, until we save the context, these changes remain in pending without affecting the data in the database. If we want to discard any changes not saved yet, we can refresh all these pending NSManagedObject
s like this:
|
|
Or we can also refresh the single object like this:
|
|
You can find more details about this function in the official documentation.
NSInvalidatedObjectsKey
This is the key for a Set
which contains all the NSManagedObject
s invalidated.
NSInvalidatedAllObjectsKey
This is the key for a boolean value which specifies if all the NSManagedObject
s in the context have been invalidated.
Usage
We can use these keys in the userInfo
dictionary of the object Notification
like this:
|
|
Note
If we use the notification NSManagedObjectContextWillSave
, we won’t have data for these keys since CoreData doesn’t know what has been saved yet.
Use Case
As we saw in the previous series about Core Data and concurrency, if we don’t use the persistent container and we want to save a private NSManagedObjectContext
, then we must save the main NSManagedObjectContext
manually. With the notifications, we can avoid this manual save
call for the main context.
In the following example, we can see how I used the notifications in StorageKit to keep the main context always updated:
|
|
To take advantage of this approach, we must have a class which contains our Core Data stack and which observers the notifications. Have a look at CoreDataStorage
for more details.
Conclusion
That’s all for the notifications of Core Data. I hope these articles are useful for all of you who are using or want to use Core Data in own applications. I’ll write another article—and probably the last one—about Core Data where I’ll show how to mock it for the unit test.
I’m going on holiday for a couple of weeks, therefore I’ll publish the next article at the end of August.
Enjoy the summer ☀️