So far I came up with the following solution:
//Assume context, entityName, nameOfRelationship,etc... to be properly defined
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:entityName];
NSArray *fetchResult = [self.context executeFetchRequest:fetchRequest error:&error];
NSArray *deletedObjects = [fetchResult filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
id relationship = [evaluatedObject changedValues][nameOfRelationship];
return relationship && ![relationship containsObject:self.currentUser];
}]];
NSArray *insertedObjects = [fetchResult filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
id relationship = [evaluatedObject changedValues][nameOfRelationship];
return relationship && [relationship containsObject:self.currentUser];
}]];
At this point I have 2 arrays of insertions and deletions (I know, I said sets in my questions... this works for now though).
The one problem I observed though, is that for this to work I need to first retrieve data from the server, parse it into managed objects, place those managed objects in their appropriate "default" relationships and then do a context save. Only after the context save will changedValues
reflect a change such as an object being deleted or inserted (if it wasn't inserted by default).
The real problem now is that a -save:
on the context saves ALL objects. So, for instance if I have 2 entities each with relations (that is 2 separate entities each with a different relation and all my example applying to both entities), if I go through the above code, then issue the POST and DELETE requests and then save the context so that at that point those objects are "committed", trying to next do the same with the other entity and its' relationship will fails since the context save clears the changedValues for all objects.