Skip to content

Instantly share code, notes, and snippets.

@rugheid
Last active June 24, 2017 16:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rugheid/cc87d672c7a68a7eef28 to your computer and use it in GitHub Desktop.
Save rugheid/cc87d672c7a68a7eef28 to your computer and use it in GitHub Desktop.
This is an update listener class to automatically update insertDate and updateDate properties for Core Data. This Gist is meant for one of my blog posts: http://www.rugenheidbuchel.be/2015/08/03/core-data-update-listener-in-swift/ Note that there is a Swift 2 and a Swift 3 version!
//
// UpdateListener.swift
// CoreDataUpdateListener
//
// Created by Rugen Heidbuchel on 03/08/15.
// Updated by Rugen Heidbuchel on 03/10/15.
// Copyright © 2015 Rugen Heidbuchel. All rights reserved.
//
import CoreData
/**
An abstract class that listens to Core Data's update notifications to set the insertDate and updateDate properties.
*/
class UpdateListener {
// MARK: Settings
/// Indicates whether UpdateListener should print updates to the console.
static var loggingEnabled = true
// MARK: Property Names
var insertDateProperty = "insertDate"
var updateDateProperty = "updateDate"
// MARK: Singleton
/// A shared UpdateListener
static let sharedInstance = UpdateListener()
/// Sets up the shared instance of UpdateListener.
static func setupSharedInstance() {
UpdateListener.sharedInstance
}
// MARK: Init
init() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "managedObjectContextWillSave:", name: NSManagedObjectContextWillSaveNotification, object: nil)
}
// MARK: Notifications
/**
This gets called when a managed object context will save. It updates all insertDate and updateDate properties.
*/
@objc func managedObjectContextWillSave(notification: NSNotification) {
// Get the managed object context from the notification
let managedObjectContext = notification.object as! NSManagedObjectContext
// Loop through the set of inserted and updated managed objects
for managedObject in managedObjectContext.updatedObjects.union(managedObjectContext.insertedObjects) {
// If it has an insertDate property, update it
if managedObject.inserted && managedObject.entity.attributesByName[insertDateProperty] != nil {
managedObject.setValue(NSDate(), forKey: insertDateProperty)
if UpdateListener.loggingEnabled {
print("Updated \(insertDateProperty) for entity of name: \(managedObject.entity.name!)")
}
}
// If it has an updateDate property, update it
if managedObject.updated && managedObject.entity.attributesByName[updateDateProperty] != nil {
managedObject.setValue(NSDate(), forKey: updateDateProperty)
if UpdateListener.loggingEnabled {
print("Updated \(updateDateProperty) for entity of name: \(managedObject.entity.name!)")
}
}
}
}
}
//
// UpdateListener.swift
// CoreDataUpdateListener
//
// Created by Rugen Heidbuchel on 03/08/15.
// Updated by Rugen Heidbuchel on 03/10/15.
// Copyright © 2015 Rugen Heidbuchel. All rights reserved.
//
import CoreData
/**
An abstract class that listens to Core Data's update notifications to set the insertDate and updateDate properties.
*/
class UpdateListener {
// MARK: Settings
/// Indicates whether UpdateListener should print updates to the console.
static var loggingEnabled = true
// MARK: Property Names
var insertDateProperty = "insertDate"
var updateDateProperty = "updateDate"
// MARK: Singleton
/// A shared UpdateListener
static let sharedInstance = UpdateListener()
/// Sets up the shared instance of UpdateListener.
static func setupSharedInstance() {
let _ = UpdateListener.sharedInstance
}
// MARK: Init
init() {
NotificationCenter.default.addObserver(
self,
selector: #selector(UpdateListener.managedObjectContextWillSave(_:)),
name: NSNotification.Name.NSManagedObjectContextWillSave,
object: nil)
}
// MARK: Notifications
/**
This gets called when a managed object context will save. It updates all insertDate and updateDate properties.
*/
@objc func managedObjectContextWillSave(_ notification: Notification) {
// Get the managed object context from the notification
let managedObjectContext = notification.object as! NSManagedObjectContext
// Loop through the set of inserted and updated managed objects
for managedObject in managedObjectContext.updatedObjects.union(managedObjectContext.insertedObjects) {
// If it has an insertDate property, update it
if managedObject.isInserted && managedObject.entity.attributesByName[insertDateProperty] != nil {
managedObject.setValue(Date(), forKey: insertDateProperty)
if UpdateListener.loggingEnabled {
print("Updated \(insertDateProperty) for entity of name: \(managedObject.entity.name!)")
}
}
// If it has an updateDate property, update it
if managedObject.isUpdated && managedObject.entity.attributesByName[updateDateProperty] != nil {
managedObject.setValue(Date(), forKey: updateDateProperty)
if UpdateListener.loggingEnabled {
print("Updated \(updateDateProperty) for entity of name: \(managedObject.entity.name!)")
}
}
}
}
}
@Adlai-Holler
Copy link

Thanks for making this! Hey, what do you think about doing this at NSManagedObjectContextObjectsDidChangeNotification instead of WillSaveNotification?

@rugheid
Copy link
Author

rugheid commented Jun 24, 2017

@Adlai-Holler: Sorry for the (2-years) late response! I guess my notifications weren't as good back then as they are now...

I looked into the NSManagedObjectContextObjectsDidChangeNotification, but I guess it would make the process a bit more complex. That notification is only called when objects are changed, not when they are added to the context. This means we would still need the other notification to set the insertDate property. I can't really tell how it would affect performance without testing it, so maybe I will do that in the near future. It would be good to test the performance impact anyhow...

It's nice to know that you like it by the way, so thanks for letting me know!

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