Friday, 23 August 2013

Newly created NSManagedObject returns temporary objectID even after save

Newly created NSManagedObject returns temporary objectID even after save

Very simple situation. Not sure why it's causing an issue.
I have a view that creates a new NSManagedObject in a child
NSManagedObjectContext. When the user presses "done", it saves the child
context, then it saves the parent context, then it posts a notification
with the newly created object's objectID. In the main view controller, I
respond to the notification and try to get the newly created object with
existingObjectWithID:error:.
Problem is this fails because the objectID is temporary (I get a "Cocoa
error 133000"). The saves to the two contexts are flawless: when I reload
the app, I can see the entries I created. But at the time I need to get a
reference to the new object, it fails.
Why does it give me a temporary object ID after I've already saved it?
Note: I have tried using obtainPermanentIDsForObjects:error:, which works,
but the permanent ID still fails when I try to use it to obtain the
object.
Here's some code:
-(IBAction)done:(id)sender
{
if ([editorDoneNotification isEqualToString:kNOTIFICATION_OBJECTADDED]) {
// save the temporary moc
NSError* e;
if (![self.tempContext save:&e]) { // this is always a successful
save
NSLog(@"Failed to save temporary managed object context: %@",
[e localizedDescription]);
[[[UIAlertView alloc] initWithTitle:@"Database Error"
message:@"Failed to add object."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil] show];
}
}
NSError* e;
if (![[[AMDataModel sharedDataModel] mainContext] save:&e]) { // this
is also successful
NSLog(@"Failed to save main managed object context: %@", [e
localizedDescription]);
[[[UIAlertView alloc] initWithTitle:@"Database Error"
message:@"Failed to edit object."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil] show];
}
else
[[NSNotificationCenter defaultCenter]
postNotificationName:editorDoneNotification
object:[self.editingObject objectID]];
[self.navigationController dismissViewControllerAnimated:YES
completion:nil];
}
And this is how I respond to the notifications:
-(void)objectAdded:(NSNotification*)notification
{
if (self.popoverController && [self.popoverController
isPopoverVisible]) {
[self.popoverController dismissPopoverAnimated:YES];
}
NSManagedObjectID* newObjectID =
(NSManagedObjectID*)(notification.object);
NSError* error;
AMObject* object = (AMObject*)[[[AMDataModel sharedDataModel]
mainContext] existingObjectWithID:newObjectID error:&error]; // this
is where the cocoa error 133000 happens
if (error != nil) {
NSLog(@"ERROR: Could not load new object in main managed object
context.");
}
GMSMarker* m = [[GMSMarker alloc] init];
m.position = CLLocationCoordinate2DMake(object.latitudeValue,
object.longitudeValue);
m.userData = object;
m.map = self.mapView;
[self.markers addObject:m];
}
-(void)objectEdited:(NSNotification *)notification
{
NSManagedObjectID* editedObjectID =
(NSManagedObjectID*)notification.object;
NSError* error = nil;
AMObject* object = (AMObject*)[[[AMDataModel sharedDataModel]
mainContext] existingObjectWithID:editedObjectID error:&error];
if (error != nil) {
NSLog(@"Error could not load edited object in main managed object
context");
}
//update the UI based on edit
if ([self.popoverController isPopoverVisible]) {
[self.popoverController dismissPopoverAnimated:YES];
self.popoverController = nil;
}
}

No comments:

Post a Comment