0

I am using a notification with the name NSManagedObjectContextDidSaveNotification and when it receives the notification, the userInfo dictionary contains all the changes just made to the context during the save. How can I extrapolate that data into my managed object model? I tried doing this

- (void)addControllerContextDidSave:(NSNotification*)saveNotification {

    NSMutableDictionary *userInfo = (NSMutableDictionary *)[saveNotification userInfo];
    NSLog(@"userInfo is %@", userInfo);
    TaskInfo *taskInfo = (TaskInfo *)[userInfo objectForKey:@"inserted"];
    NSLog(@"taskInfo is %@", taskInfo);
}

Where TaskInfo is my custom managed object model. And that printed this

    userInfo is {
        inserted = "{(\n    <TaskInfo: 0x15f350> (entity: TaskInfo; id: 0x13fda0 <x-       coredata://1F98E14E-259F-4CB3-84E2-9AC8466CCD1B/TaskInfo/p2> ; data: {\n    completionDate = nil;\n    creationDate = \"2011-12-08 02:14:04 +0000\";\n    duration = 10860;\n    elapsedTime = 0;\n    isCompleted = 0;\n    isRepeating = 0;\n    isRunning = 0;\n    isToday = 0;\n    projectedEndTime = nil;\n    specifics = nil;\n    startTime = nil;\n    timesReminded = 0;\n    title = haha;\n})\n)}";
        updated = "{(\n)}";
    }
    2011-12-07 20:14:54.147 Tisk Task 3[3161:707] taskInfo is {(
        <TaskInfo: 0x15f350> (entity: TaskInfo; id: 0x13fda0 <x-coredata://1F98E14E-259F-    4CB3-84E2-9AC8466CCD1B/TaskInfo/p2> ; data: {
        completionDate = nil;
        creationDate = "2011-12-08 02:14:04 +0000";
        duration = 10860;
        elapsedTime = 0;
        isCompleted = 0;
        isRepeating = 0;
        isRunning = 0;
        isToday = 0;
        projectedEndTime = nil;
        specifics = nil;
        startTime = nil;
        timesReminded = 0;
        title = haha;
    })
    )}

I think the issue is the extra set of {()} on the outside of the TaskInfo model. Anyone have any suggestions?

gurooj
  • 2,100
  • 4
  • 21
  • 25

2 Answers2

1

That outer {()} is telling you that [userInfo objectForKey:@"inserted"] is actually returning an NSSet containing a single TaskInfo, not the TaskInfo itself.

I'm not sure what exactly you mean by "extrapolate that data into my managed object model", but if it means "update another NSManagedObjectContext so that those freshly saved changes appear in it", there's an easier way:

Take a look at mergeChangesFromContextDidSaveNotification: in the manual. It takes a NSManagedObjectContextDidSaveNotification fired by context A, and puts all the changes just saved into context B. No poking around the notification's userInfo needed.

rgeorge
  • 7,385
  • 2
  • 31
  • 41
  • I'm always adding one object at at time, so I was hoping I could get direct access to the entity being added at the moment. Is there a reasonable way to do this? Once that entity is in context B (assuming it came from A), I would then have to search the context and fetch the object, right? But I already know what the task is, so I just want direct access to it. – gurooj Dec 08 '11 at 02:53
  • In that case it might be reasonable to scrounge the notification userinfo for the objectID(s), after doing the mergeChangesFromContextDidSaveNotification, and ask your context for objects by ID. That way you get object(s) associated with the correct context. The takeaway from your original question is that the notification userinfo always contains sets of objects, even if there's only one. – rgeorge Dec 08 '11 at 03:23
  • Ok, Thank you. I will try that. How would I go about extracting that ID? I have done very little string work for objective-c. If you knew a good website, that would be even better. Thanks for the help so far. – gurooj Dec 08 '11 at 03:34
  • the `objectID` method on `NSManagedObject` returns the object's primary key. It's not a string, but it has a URL form that can be stringified if you need to (you won't need to.) See http://stackoverflow.com/questions/5035057 for how to use them to load objects. – rgeorge Dec 08 '11 at 04:12
  • No, I understand that. I meant how do I get it out of that NSSet? – gurooj Dec 08 '11 at 04:24
  • the `anyObject` method is handy for such things, if you know there's only one. e.g. `[[userInfo objectForKey:@"inserted"] anyObject]` in context above. – rgeorge Dec 08 '11 at 05:12
0

So I ended up finding a solution to my own problem, by finding the task's objectID right before it is saved in the AddViewController delegate, and passing that to the main table view I was using in a notification. Much easier than trying to parse the changelog in the userInfo dictionary of NSManagedObjectContextDidSaveNotification.

gurooj
  • 2,100
  • 4
  • 21
  • 25