Overview
- I have an iOS project in which I am using Core data
- I am inserting an object, then I want to save it.
- I am not sure if save works.
- Save seems to be working when app goes into background
- When using Simulator, If I click on Stop button on Xcode, save doesn’t seem to be working.
Question
- Is the save actually happening ?
- Am I facing a problem because I created a view based app (the core data checkbox was not available) ?
Steps Followed
- I am using the simulator to test it.
- Insert an object (code is in the next section)
- Save the inserted object (code is in the next section)
- I press the Stop button on Xcode to stop running the app
Output noticed
setBeforeSave.count = 1
setAfterSave.count = 0
- Before saving, The
NSManagedObjectContextmethodinsertedObjectsreturns 1 object - Before saving, The
NSManagedObjectContextmethodinsertedObjectsreturns 0 objects - When Xcode Stop button is pressed, and when the app is relaunched, the previous data is not available (is it because I clicked on stop on xcode)
- managedObjectContext is NOT nil
- The
NSManagedObjectContextmethodsave:returnsYES.
Code to Insert Object
Test *test = [NSEntityDescription insertNewObjectForEntityForName:@"Test" inManagedObjectContext:self.database.managedObjectContext];
Code to Save:
//database is a property of the type UIManagedDocument
NSSet *setBeforeSave = [self.database.managedObjectContext insertedObjects];
NSLog(@"setBeforeSave.count = %i", setBeforeSave.count);
NSError *error = nil;
if(![self.database.managedObjectContext save:&error])
NSLog(@"error = %@", error);
NSSet *setAfterSave = [self.database.managedObjectContext insertedObjects];
NSLog(@"setAfterSave.count = %i", setAfterSave.count);
According to the UIManagedDocument documentation, you should not call save on either of the internal managed contexts. Instead, if you want data saved, you should do one of two things.
Use the undoManager, as it will mark the context dirty, and ready to be saved.
Call [document updateChangeCount:UIDocumentChangeDone];
Thus, in your case, you should replace that save call with:
And your data will get saved.
EDIT
To provide additional detail. A UIManagedDocument has two MOCs., in a parent/child relationship. The child is the one you get when calling document.managedObjectContext. Now, when a NSManagedObjectContext has a parent, the normal way to propagate changes to the parent is to call save:. However, the UIManagedDocuememt does other stuff, and its documentation specifically says NOT to call save on either the parent or child context.
Well, how does stuff get saved, then? Well, you tell the UIManagedDocument that it is “dirty” and needs to be saved. The two ways you can do that are by either using the undoManager, or calling updateChangeCount:.
When doing either of those, the internals of UIManagedDocument will make sure that the parent context is notified of the change. At some point in the future, the parent will effect the change to the actual backing store (i.e., file(s) on disk).
Furthermore, when a context is “saved” it may or may not keep references to the objects that were changed. You can set a property which tells it to retain objects that have been saved, or to release them.
Hopefully, that addresses your problems.
to summarize, though, see the original answer.
BTW, you can actually see a log of what the SQL store is doing underneath by adding “-com.apple.CoreData.SQLDebug 1” to your command line arguments. You do that in the “Edit Scheme” dialog.