Z S
Z S

Reputation: 7511

Observing NSArrayController changes: detect insertion or deletion

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?

Upvotes: 2

Views: 1296

Answers (1)

stevesliva
stevesliva

Reputation: 5655

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");
        }
    }

}

Upvotes: 4

Related Questions