0

Can you suggest how I can customize my NSManagedObjects so that a Rep entity can associate with a Day entity dynamically both when a Rep entity is created and when it's date property is changed?

I need help with the NSPredicate to search for Days that have the same DD/MM/YYYY as the created Rep entity and I need to know which NSManagedObject methods to override when the Rep entity is created and when it's date property is changed.

I've attached a design flow chart to clarify.

Thanks in advance.

enter image description here

Lorenzo B
  • 33,216
  • 24
  • 116
  • 190
aaronium112
  • 2,992
  • 4
  • 35
  • 50

1 Answers1

1

Here some suggestions to achieve what you want. For clarity I will divide my answer in two parts. The first regards the left part of your flow chart.

Left part

When you create a Rep you need to set up its date (Note A). For this I would override awakeFromInsert method. As per the documentation

You typically use this method to initialize special default property values. This method is invoked only once in the object's lifetime.

Once inserted the new object, you should run fetch request against Day with a specific predicate for searching for the same date.

Here you cannot simply use a predicate like

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(eDate = %@)", selectedDate];

It won't work. Instead use a solution described in Core Data Predicate Date Comparison. The motivation is that an data 15/03/2014 16:02:00 will not match with 15/03/2014 16:02:01.

Based on the results returned from the fetch request you will grab the first object (Note B) in the array and set up the relationship. On the contrary you will create a new Day object and set up the relationship.

Note A This means you've created subclasses of NSManagedObject for Rep and Day Note B How many Days do you except to find?

Right part

For the second part I will rely on NSManagedObjectContextObjectsDidChangeNotification. This notification is useful for listen for changes that occur.

When a changes occur the notification will contain NSSet for deleted, inserted or updated objects.

NSSet *updatedObjects = [[notification userInfo] valueForKey:NSUpdatedObjectsKey];
NSSet *deletedObjects = [[notification userInfo] valueForKey:NSDeletedObjectsKey];
NSSet *insertedObjects = [[notification userInfo] valueForKey:NSInsertedObjectsKey];

// Place your logic here...

Obvioulsy you need to replace the comment with your logic there. It looks like the previous. But the important thing is to filter the objects that are returned in the notification. You are interested only for changes to Rep. So, for example

NSSet *objects = nil;
NSMutableSet *combinedSet = nil;
NSPredicate *predicate = nil;

NSDictionary *userInfo = [notification userInfo];

objects = [userInfo valueForKey:NSInsertedObjectsKey];
combinedSet = [NSMutableSet setWithSet:objects];

objects = [[notification userInfo] valueForKey:NSUpdatedObjectsKey];
[combinedSet unionSet:objects];

objects = [[notification userInfo] valueForKey:NSDeletedObjectsKey];
[combinedSet unionSet:objects];

predicate = [NSPredicate predicateWithFormat:@"entity.name == %@, 
              @"Rep"];
[combinedSet filterUsingPredicate:predicate];

if ([combinedSet count] == 0) {
    return;
}

// Place your logic here…

Finally, to maintain the consistency graph I would use a cascade relationships from Rep to Day and nullify to Day to Rep. This will allow you to remove Days objects if are not attached to any Rep. Obviously it depends on your needs.

Hope it helps.

Community
  • 1
  • 1
Lorenzo B
  • 33,216
  • 24
  • 116
  • 190
  • Where should I put the code to observe to changes to the managed object context? For example I want to observe rep.date from Day...but day doesn't always exist in the managedObjectContext, sometimes it only exists as a fault. – aaronium112 Aug 15 '14 at 18:28