I am trying to load a table view with cells that represents people, loaded from core data. This is how I get the context:
@property (nonatomic,strong) NSManagedObjectContext* managedObjectContext;
...
- (NSManagedObjectContext*) managedObjectContext {
if(!_managedObjectContext) {
NSFileManager* manager= [NSFileManager defaultManager];
NSURL* URL= [manager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].firstObject;
URL= [URL URLByAppendingPathComponent:@"PeopleDocument"];
UIManagedDocument* document= [[UIManagedDocument alloc]initWithFileURL:URL];
if([manager fileExistsAtPath:URL.path]) {
[document openWithCompletionHandler:^(BOOL success) {
}];
} else {
[document saveToURL:URL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
}];
}
NSManagedObjectContext* context= [document managedObjectContext];
_managedObjectContext= context;
}
return _managedObjectContext;
}
Then just the first time that I run the app I insert a new entity and save the context:
[NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext: self.managedObjectContext];
[self.managedObjectContext save:NULL];
I also tried to log the result of save:
, it returns YES
and there's no error. But the context isn't truly saved: the second time that I run the app the fetched entities array is empty.
Update
Something even stranger happened: reading this answer to another similar question, I've found a method to force the document to be saved:
- (void) save {
NSError *error = nil;
if (![self.managedObjectContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
[self.managedDocument saveToURL:self.managedDocument.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success)
{
NSLog(@"Saved: %d",success);
}];
}
So I execute this code the first time that I run the app:
#if FIRST_TIME
[NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext: self.managedObjectContext];
[self save];
#endif
After it, if I set FIRST_TIME
to zero, the second time that I run the app I get empty records. But if the 3rd time that I run the app I set again FIRST_TIME
to 1, then I get all the records that I created before (plus the one that gets created). This means that if I create and save new entities, all the entities that I created before are fetched correctly, otherwise no entity is fetched.
PS: I double checked: the managed object context is the exact one returned by self.managedDocument.managedObjectContext
.
I just changed my way to create the managed object context. Instead of using a UIManagedDocument
, I created the context with alloc
+initWithConcurrencyType:
, then I set it's persistent store coordinator:
- (NSManagedObjectContext*) managedObjectContext {
if(!_managedObjectContext) {
NSURL* URL= [[NSBundle mainBundle] URLForResource:@"People" withExtension:@"momd"];
NSManagedObjectModel* model= [[NSManagedObjectModel alloc]initWithContentsOfURL:URL];
NSPersistentStoreCoordinator* storeCoordinator= [[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel: model];
NSURL* storeURL= [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].lastObject;
storeURL= [storeURL URLByAppendingPathComponent:@"MOC.sqlite"];
NSError* error;
[storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error];
if(error) {
NSLog(@"Cannot create new store %@",error);
return nil;
}
_managedObjectContext= [[NSManagedObjectContext alloc]initWithConcurrencyType: NSMainQueueConcurrencyType];
_managedObjectContext.persistentStoreCoordinator= storeCoordinator;
}
return _managedObjectContext;
}
I believe that also the other way is correct, but maybe I had to save the document in another way.