I have an NSArrayController that is bound to an entity "Address" in my Core Data model. I want to monitor which new objects are inserted into this Address entity, or which existing objects are deleted. I'm trying to do this through KVO, but I'm not sure how I should go about this.
In my awakeFromNib, I add the view controller class as the observer for "arrangedObjects":
[self.addressArrayController addObserver:self
forKeyPath:@"arrangedObjects"
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context:@"Address"];
and I do get the observer notifications in this:
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if( object == self.addressArrayController) {
// what do do here?
}
}
The problem is that the change dictionary is always nil (due to some long-standing Apple bug, I believe), so I have no idea which object was added or deleted, or even something was added or deleted! And I do need the exact object that was added or deleted, ideally without having to traverse all the objects for this entity and trying to figure out based on the object's timestamp or any other criterion.
What is the best way to do this?
Adapted from my answer here, which lays out the code for what gaige suggests in the comments.
Register for NSManagedObjectContextObjectsDidChangeNotification:
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(mocDidChangeNotification:)
name:NSManagedObjectContextObjectsDidChangeNotification
object: nil];
And parse the userInfo dictionary in the corresponding method:
- (void)mocDidChangeNotification:(NSNotification *)notification
{
NSManagedObjectContext* savedContext = [notification object];
// Ignore change notifications for anything but the mainQueue MOC
if (savedContext != self.managedObjectContext) {
return;
}
// Ignore updates -- lots of noise from maintaining user-irrelevant data
// Log insertion
for (NSManagedObject* insertedObject in
[notification.userInfo valueForKeyPath:NSInsertedObjectsKey])
{
if ([insertedObject isKindOfClass:[Address class]] )
{
NSLog(@"Inserted Address");
}
}
// Log deletion
for (NSManagedObject* deletedObject in
[notification.userInfo valueForKeyPath:NSDeletedObjectsKey])
{
if ([deletedObject isKindOfClass:[Address class]] )
{
NSLog(@"Deleted Address");
}
}
}