I have an app that is working with core-data. At the moment I'm on V1.5, during those versions I've made some changes to the core database. After some complaints of people that the app is still crashing I found out that I should have implemented Core data lightweight
. The problem is now, I don't know anymore what I've changed in the different versions.
Also for working with core data I followed the video tutorial from Standford University. It is lesson 13 over here.
When you look at this tutorial you see that he does not work with the standard code XCODE generates in the appdelegate. I will explain in short what he is doing.
In de ViewWillAppear
I check if there is a managed document. If there isn't, I create one.
if (!self.genkDatabase) {
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:@"Default appGenk Database"];
// url is now "<Documents Directory>/Default Photo Database"
self.genkDatabase = [[UIManagedDocument alloc] initWithFileURL:url]; // setter will create this for us on disk
}
When a document is set I call the UseDocument
function
- (void)setGenkDatabase:(UIManagedDocument *)genkDatabase
{
if (_genkDatabase != genkDatabase) {
_genkDatabase = genkDatabase;
[self useDocument];
}
}
Then in the useDocument I check what the document state is, en then get and save my data in the core database.
- (void)useDocument
{
if (![[NSFileManager defaultManager] fileExistsAtPath:[self.genkDatabase.fileURL path]]) {
// does not exist on disk, so create it
[self.genkDatabase saveToURL:self.genkDatabase.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
NSLog(@"no database created yet");
[self fetchNewsIntoDocument:self.genkDatabase];
[self setupFetchedResultsController];
}];
} else if (self.genkDatabase.documentState == UIDocumentStateClosed) {
// exists on disk, but we need to open it
NSLog(@"closed");
[self.genkDatabase openWithCompletionHandler:^(BOOL success) {
[self fetchNewsIntoDocument:self.genkDatabase];
[self setupFetchedResultsController];
}];
} else if (self.genkDatabase.documentState == UIDocumentStateNormal) {
// already open and ready to use
[self setupFetchedResultsController];
}
}
This is how I fetch my data into the database.
- (void)fetchNewsIntoDocument:(UIManagedDocument *)document
{
dispatch_queue_t fetchNews = dispatch_queue_create("news fetcher", NULL);
dispatch_async(fetchNews, ^{
NSArray *news = [GenkData getNews];
[document.managedObjectContext performBlock:^{
int newsId = 0;
for (NSDictionary *genkInfo in news) {
newsId++;
[News newsWithGenkInfo:genkInfo inManagedObjectContext:document.managedObjectContext withNewsId:newsId];
}
[document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL];
}];
});
dispatch_release(fetchNews);
}
I know this is a lot of code but I would like to get a good answer, because I'm searching after this problem for days. Before I've heard of lightweight core data migration I didn't have anything in my appdelegate concerning core data. After the research of lightweight migration I've added the standard core-dat code in my appdelegate and also added this to the code.
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Default appGenk Database.sqlite"];
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil];
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSDictionary *options = @{
NSMigratePersistentStoresAutomaticallyOption : @YES,
NSInferMappingModelAutomaticallyOption : @YES
};
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
Now after alot of code we are getting to the actual problem. When I run the project on an iPad that has installed the very first build, I get the following error after that it has inserted the data into the database.
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'This NSPersistentStoreCoordinator has no persistent stores. It cannot perform a save operation.'
I hope that anybody can help me with this problem. I'm not so long an IOS Developer and it's hard to solve this problem for me.
Kind regards