Brock Boland
Brock Boland

Reputation: 16650

Is there a good way to update an NSManagedObject when relationships change?

This is a simplified version of my scenario, but that's OK.

Let's say you have three CoreData entities, each with a corresponding subclass of NSManagedObject, and 1-to-1 relationships as follows:

Person -> ContactRecord -> PhoneNumber

The Person entity has a vcard attribute, which holds the vCard data for that person in a string.

The PhoneNumber entity has two attributes: the actual number, and the type of phone number (cell, home, work, etc).

Right now, in the Person willSave method, I'm updating the vcard property. This works fine, if another property on the Person object has changed. But, if I change the type or number on the PhoneNumber object, or any properties on the ContactRecord, the willSave method isn't called on the Person object.

Is there a good way to update the Person object when a property changes over on the PhoneNumber object?

Right now, the best option I see is using NSManagedObjectContextWillSaveNotification. The method called by that notification could sift through the changed objects and work back up the inverse relationships to call some method on the Person object, but this happens after the NSManagedObjectContext has already saved, so it would require another save after that. My hope was to set this property to the correct value before the save happens.

Upvotes: 2

Views: 654

Answers (2)

Drew McCormack
Drew McCormack

Reputation: 3592

The NSManagedObjectContextWillSaveNotification method is called just before the save occurs, so you could make the change there and it should not need a second save.

My preference in a situation like this would be to not store the vcard at all, but make it a dependent property that is readonly. I assume you don't need to access the vcard very often, so generating the data on-the-fly in the getter method should work OK, and the data will always be up-to-date.

One problem with updating the data just before a save is that you have to make sure you save. If you try to get the vcard without saving, it will be out-of-date. The dependent read-only property won't have that issue.

Upvotes: 1

Marcus S. Zarra
Marcus S. Zarra

Reputation: 46718

A straight-forward way is to continue to use the -willSave: method in the children. When the -willSave: fires on ContactRecord then ping the parent and ask it to recalculate the vcard. You can do the same thing for PhoneNumber. Just work back up the relationships.

This is assuming your relationships are bi-directional which, while flagged as a warning, really is a requirement with Core Data.

Upvotes: 1

Related Questions