Reputation: 3172
We have a pretty robust and fleshed-out system for detecting changes on the models in our iOS app using NSManagedObjectContextObjectsDidChangeNotification
. This works well for our attribute changes as well as changes in 1:1 and 1:M relationships.
We're trying to build in some M:M relationships to our schema now and I'm struggling to see how Coredata's notification system will allow us to observe specific changes in M:M relationships.
I'm guessing that if a M:M relationship changed, the two objects involved in the change would both appear in the NSUpdatedObjectsKey
list, but there wouldn't be any specific annotation to say that a M:M relationship between them had changed, or which M:M relationship that was (assuming there are possibly more than one M:M relationship between two models).
Has anyone had any luck in using Coredata's notifications system to detect changes in M:M relationships? Or are they basically difficult to work with and people tend to resort to explicitly creating the "joining table" as a real type (and thereby ending up with two 1:M relationships instead of a single M:M relationship)?
Upvotes: 1
Views: 1161
Reputation: 7327
You are correct: when a M:M relationship changes, the objects at both ends of the relationship show up in the appropriate dictionaries in the NSManagedObjectContextObjectsDidChangeNotification
.
If you're scanning the objects looking for the specific properties that have changed, you can use the method changedValues
(or, better, changedValuesForCurrentEvent
on ios5) to find out the property names. You are probably already doing this.
You can then inspect the model to see if any given property is many:many or not:
-(void)notifyObjectsChanged:(NSNotification *)note
{
assert([NSManagedObjectContextObjectsDidChangeNotification isEqual:note.name]);
for (NSManagedObject *mo in [note.userInfo objectForKey:NSUpdatedObjectsKey])
{
NSLog(@"for %@ :", mo.objectID);
NSDictionary *rels = mo.entity.relationshipsByName;
for (NSString *prop in [mo.changedValuesForCurrentEvent allKeys])
{
NSRelationshipDescription *rel = [rels objectForKey:prop];
if (rel.isToMany && rel.inverseRelationship.isToMany)
NSLog(@"many-to-many relationship %@ changed", prop);
}
}
}
(untested, off the top of my head, watch for typos!)
The essential technique is that managed objects keep references to the object model description, which you can inspect at runtime.
Upvotes: 2