New project and old Core Data Model - ios

I do have an existing project with a Core Data model. I am trying to run a new project (on top of the old model) and read what it's in the model itself.
Now, the app runs smoothly on top of the previous one. I have imported the .xcdatamodeld and nothing is crashing. However when I try to get some values from an Entity that should have some (since I have loaded it before from the old project), I get 0 as results.
I am new to Core Data, so I might be missing something really simple.
This is my current persistentStoreCoordinator (which I have found here: Coredata after Application Update):
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"Model"];
NSManagedObjectModel *managedObjectModel = [self managedObjectModel];
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: managedObjectModel];
// Check if we already have a persistent store
if ( [[NSFileManager defaultManager] fileExistsAtPath: [storeURL path]] ) {
NSLog(#"We have a persistent store!");
NSDictionary *existingPersistentStoreMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType: NSSQLiteStoreType URL: storeURL error: &error];
if ( !existingPersistentStoreMetadata ) {
// Something *really* bad has happened to the persistent store
//[NSException raise: NSInternalInconsistencyException format: #"Failed to read metadata for persistent store %#: %#", storeURL, error];
NSLog(#"Failed to read metadata for persistent store %#: %#", storeURL, error);
}
if ( ![managedObjectModel isConfiguration: nil compatibleWithStoreMetadata: existingPersistentStoreMetadata] ) {
if ( ![[NSFileManager defaultManager] removeItemAtURL: storeURL error: &error] )
NSLog(#"*** Could not delete persistent store, %#", error);
} // else the existing persistent store is compatible with the current model - nice!
NSLog(#"Existing store is compatible!");
} // else no database file yet
[_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeURL
options:nil
error:&error];
return _persistentStoreCoordinator;
}
I get the logs "we have a persistent store" and "existing store is compatible", so I am assuming I am actually finding the core data model that is saved on the device.
This is my managedObjectModel:
- (NSManagedObjectModel *)managedObjectModel {
// The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
if (_managedObjectModel != nil) {
NSLog(#"Not Null!");
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"Model" withExtension:#"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
This is how I am trying to read the data (I am calling the method in didFinishLaunchingWithOptions):
-(void) readData {
NSManagedObjectContext *context = [self managedObjectContext];
if(context != nil)
NSLog(#"not null");
NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:# "StaffAccount"];
NSError* error = nil;
NSArray* results = [context executeFetchRequest:request error:&error];
if (!results || error) { // nil is an error
// handle error
NSLog(#"Errore!");
}
NSArray *arr = [context executeFetchRequest:request error: &error];
NSInteger count = [arr count];
NSLog(#"%ld", (long)count);
}

Related

Core Data: The model used to open the store is incompatible with the one used to create the store

My app contains 2 databases:
db1: A read/write database (to store all the user settings)
db2: A readonly database, preloaded in another project (i copied .sqlite, .xcdatamodeld and entities class in the project)
If i initialize Core Data with 2 MOC and 2 PSC (one for each database): everything works fine. But i would like to initialize only 1 MOC/PSC for the two databases. To do this, i wrote the following code:
- (NSManagedObjectContext *)managedObjectContext
{
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return _managedObjectContext;
}
- (NSManagedObjectModel *)managedObjectModel
{
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
NSURL *db1ModelURL = [[NSBundle mainBundle] URLForResource:#"db1" withExtension:#"momd"];
NSManagedObjectModel *db1Mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:db1ModelURL];
NSURL *db2ModelURL = [[NSBundle mainBundle] URLForResource:#"db2" withExtension:#"momd"];
NSManagedObjectModel *db2Mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:db2ModelURL];
NSAssert(db1 != nil, #"Error initializing Managed Object Model");
NSAssert(db2 != nil, #"Error initializing Managed Object Model");
_managedObjectModel=[NSManagedObjectModel modelByMergingModels:[NSArray db1Mom,db2Mom, nil]];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
NSURL * db1URL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"db1.sqlite"];
NSURL *db2URL = [[NSBundle mainBundle] URLForResource:#"db2" withExtension:#"sqlite"];
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
_persistentStoreCoordinator = [[self managedObjectContext] persistentStoreCoordinator];
NSMutableDictionary * db2Options=[NSMutableDictionary dictionaryWithObjectsAndKeys:
#YES,NSReadOnlyPersistentStoreOption,
nil];
NSPersistentStore *store = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:#"DB2" URL:db2URL options:db2Options error:&error];
NSAssert(store != nil, #"Error initializing PSC: %#\n%#", [error localizedDescription], [error userInfo]);
NSMutableDictionary * db1Options=[NSMutableDictionary dictionaryWithObjectsAndKeys:
#YES,NSMigratePersistentStoresAutomaticallyOption,
#YES,NSInferMappingModelAutomaticallyOption,
nil];
store = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:#"DB1" URL:db1URL options:db1Options error:&error];
NSAssert(store != nil, #"Error initializing PSC: %#\n%#", [error localizedDescription], [error userInfo]);
return _persistentStoreCoordinator;
}
And when i launch the app, i get the following error on the DB2 database:
The model used to open the store is incompatible with the one used to create the store
I think the problem comes with the call to modelByMergingModels, the resulting model contains the db2Model, but Core Data doesn't recognize it as the base model for this database...
Suggestions?
It is happening because you initially installed the app in your phone using one of the db. Now you have added/changed the DB. So it does not recognise the new DB. Because the app was originally created/installed using a different DB.
Try deleting the app from you phone and install again. The error will go.
Hope this helps. :)
I found a solution reading this article. Even if i don't understand why it works...
- (void)initializeCoreData{
// Initialize models
NSURL *db2ModelURL = [[NSBundle mainBundle] URLForResource:#"villes" withExtension:#"momd"];
NSManagedObjectModel *db2Mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:db2ModelURL];
NSAssert(db2Mom != nil, #"Error initializing Managed Object Model");
NSURL *db1ModelURL = [[NSBundle mainBundle] URLForResource:#"MMAMeteoPro" withExtension:#"momd"];
NSManagedObjectModel *db1Mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:db1ModelURL];
NSAssert(db1Mom != nil, #"Error initializing Managed Object Model");
NSManagedObjectModel * fullModel=[NSManagedObjectModel modelByMergingModels:[NSArray arrayWithObjects:db1Mom,db2Mom, nil]];
// Initialize context
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:fullModel];
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[moc setPersistentStoreCoordinator:psc];
[self setManagedObjectContext:moc];
// Initialize stores
NSURL *db2StoreURL = [[NSBundle mainBundle] URLForResource:#"db2" withExtension:#"sqlite"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *documentsURL = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *db1StoreURL = [documentsURL URLByAppendingPathComponent:#"db1.sqlite"];
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
NSError *error = nil;
NSPersistentStoreCoordinator *psc = [[self managedObjectContext] persistentStoreCoordinator];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
nil];
NSMutableDictionary * db2Options=[NSMutableDictionary dictionaryWithObjectsAndKeys:
#{#"journal_mode":#"DELETE"},NSSQLitePragmasOption,
#YES, NSReadOnlyPersistentStoreOption,
nil];
NSMutableDictionary * db1Options=[NSMutableDictionary dictionaryWithObjectsAndKeys:
#{#"journal_mode":#"DELETE"},NSSQLitePragmasOption,
nil];
NSPersistentStore * tempStore = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:db2StoreURL options:options error:&error];
NSAssert(error == nil, #"Error initializing PSC: %#\n%#", [error localizedDescription], [error userInfo]);
[psc removePersistentStore:tempStore error:&error];
NSAssert(error == nil, #"Error initializing PSC: %#\n%#", [error localizedDescription], [error userInfo]);
tempStore=[psc addPersistentStoreWithType:NSSQLiteStoreType configuration:#"DB2Conf" URL:villeStoreURL options:db2Options error:&error];
NSAssert(error == nil, #"Error initializing PSC: %#\n%#", [error localizedDescription], [error userInfo]);
tempStore=[psc addPersistentStoreWithType:NSSQLiteStoreType configuration:#"DB1Conf" URL:meteoStoreURL options:db1Options error:&error];
NSAssert(error == nil, #"Error initializing PSC: %#\n%#", [error localizedDescription], [error userInfo]);
});
}
We have to:
Add the ReadOnly persistent store first, with the lightweight migration options on, and no ReadOnly option nor configuration
Remove this persistent store (???)
Add it again, this time without the lightweight migration options, but with the ReadOnly and the good configuration.
Add the Read/Write Persistent Store
If someone can explain me why this configuration works... Cause i really don't get the point here.

iCloud with Core Data, Data Persistency When iCloud is Off

I would like to add iCloud to my Core Data app. The only thing I want out of iCloud is the persistence of data through deletion and re-installation of the App. I do not need multiple device support for the app at the moment. I have managed the iCloud work with Core Data. However, there is one scenario that I am not sure how to handle. Right now, if the iCloud is on for the app, the data that is saved in the iCloud persists through deletion and re-installation of the app which is what I want. But when the user turns off the iCloud for the app, the data that was saved in the iCloud does not show anymore which I think is normal and when user creates new data, the new data is saved in the local storage of the app. So it looks like that I have two separate storages, one iCloud and one local. So my question is, when the iCloud is off and data values are created and saved into the local storage of the app, how to make sure those data values get added to the data values that were saved in the iCloud, when the iCloud is turned back on?
Here is the relevant section of my App Delegate:
- (NSManagedObjectContext *)managedObjectContext {
if (_managedObjectContext != nil)
{
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (!coordinator)
{
return nil;
}
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
return _managedObjectContext;
}
- (NSManagedObjectModel *)managedObjectModel
{
if (_managedObjectModel != nil)
{
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"Model" withExtension:#"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
NSURL *documentsDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSURL *storeURL = [documentsDirectory URLByAppendingPathComponent:#"Model.sqlite"];
NSError *error = nil;
NSString *failureReason = #"There was an error creating or loading the application's saved data.";
NSDictionary *storeOptions =
#{NSPersistentStoreUbiquitousContentNameKey: #"MyAppCloudStore"};
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:storeOptions error:&error]) {
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[NSLocalizedDescriptionKey] = #"Failed to initialize the application's saved data";
dict[NSLocalizedFailureReasonErrorKey] = failureReason;
dict[NSUnderlyingErrorKey] = error;
error = [NSError errorWithDomain:#"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}

iOS App mistakenly creating multiple sqlite files for a test case, thus leading to repetitive file downloads

I have implemented core data in my ios app. Now when downloading and saving files to database, if I quit the process in between and then start again it creates new sqlite file everytime. This leads to app taking files from database for first few files, while storing the later files in a seperate database which it doesn't access later. This eventually leads to downloading of later files everytime and creating a new database for it. I am pretty confused on how to fix this. Following is my core data code from AppDelegate class, hoever, I need to run the operation continued in background also , so no fixing there:
#pragma mark - Core Data stack
#synthesize managedObjectContext = _managedObjectContext;
#synthesize managedObjectModel = _managedObjectModel;
#synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
- (NSURL *)applicationDocumentsDirectory {
// The directory the application uses to store the Core Data store file. This code uses a directory named "acme.in.EcoGrid" in the application's documents directory.
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
- (NSManagedObjectModel *)managedObjectModel {
// The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"EcoGrid" withExtension:#"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
// The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it.
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
// Create the coordinator and store
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"EcoGrid.sqlite"];
NSError *error = nil;
NSString *failureReason = #"There was an error creating or loading the application's saved data.";
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
// Report any error we got.
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[NSLocalizedDescriptionKey] = #"Failed to initialize the application's saved data";
dict[NSLocalizedFailureReasonErrorKey] = failureReason;
dict[NSUnderlyingErrorKey] = error;
error = [NSError errorWithDomain:#"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
- (NSManagedObjectContext *)managedObjectContext {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (!coordinator) {
return nil;
}
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
return _managedObjectContext;
}
#pragma mark - Core Data Saving support
- (void)saveContext {
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
NSError *error = nil;
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}
}
-(void)deleteAndRecreateStore{
NSPersistentStore * store = [[self.persistentStoreCoordinator persistentStores] lastObject];
NSError * error;
[self.persistentStoreCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtURL:[store URL] error:&error];
_managedObjectContext = nil;
_persistentStoreCoordinator = nil;
[self managedObjectContext];
}
Any help here is highly appreciated!
Looks like the problem is resolved by placing an if condition in persistentStore Coordinator method like this:-
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
// The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it.
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
// Create the coordinator and store
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: [[[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"EcoGrid.sqlite"] absoluteString] ] == NO) {
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"EcoGrid.sqlite"];
NSError *error = nil;
NSString *failureReason = #"There was an error creating or loading the application's saved data.";
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
// Report any error we got.
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[NSLocalizedDescriptionKey] = #"Failed to initialize the application's saved data";
dict[NSLocalizedFailureReasonErrorKey] = failureReason;
dict[NSUnderlyingErrorKey] = error;
error = [NSError errorWithDomain:#"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}
else{
}
return _persistentStoreCoordinator;
}

SQLite Error 266 on CoreData DB

With my most recent app update, I have started to see very inconsistent SQLite errors when saving my database. These are happening with multiple users, so it is not just the same user crashing repeatedly (though it has happened for the same user multiple times). I am getting error 266, which is SQLITE_IOERR_READ. I haven't found anyone else running into this error, so not sure why I'm getting it.
00:04:18:25 $ -[AppDelegate saveContext] line 328 $ Unresolved error Error Domain=NSCocoaErrorDomain Code=266 "The operation couldn’t be completed. (Cocoa error 266.)" UserInfo=0x1dd141b0 {NSSQLiteErrorDomain=266, NSFilePath=/var/mobile/Applications/[omitted], NSPOSIXErrorDomain=1, NSUnderlyingException=I/O error for database at /var/mobile/Applications/[omitted]. SQLite error code:266, 'not an error' errno:1}, {
* 00:04:18:25 NSFilePath = "/var/mobile/Applications/[omitted].sqlite";
* 00:04:18:25 NSPOSIXErrorDomain = 1;
* 00:04:18:25 NSSQLiteErrorDomain = 266;
* 00:04:18:25 NSUnderlyingException = "I/O error for database at /var/mobile/Applications/[omitted].sqlite. SQLite error code:266, 'not an error' errno:1";
* 00:04:18:25 }
EDIT
Here is the core-data related code (most of it standard boilerplate):
/**
Returns the managed object context for the application.
If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
*/
- (NSManagedObjectContext *) managedObjectContext {
if (managedObjectContext != nil) {
return managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator: coordinator];
}
return managedObjectContext;
}
/**
Returns the managed object model for the application.
If the model doesn't already exist, it is created by merging all of the models found in the application bundle.
*/
- (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel != nil) {
return managedObjectModel;
}
//managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
// See http://iphonedevelopment.blogspot.com.au/2009/09/core-data-migration-problems.html
NSString *path = [[NSBundle mainBundle] pathForResource:#"modelDB" ofType:#"momd"];
NSURL *momURL = [NSURL fileURLWithPath:path];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];
return managedObjectModel;
}
/**
Returns the persistent store coordinator for the application.
If the coordinator doesn't already exist, it is created and the application's store added to it.
*/
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSString *storePath = [[Utils documentsDirectory] stringByAppendingPathComponent: #"modelDB.sqlite"];
NSURL *storeUrl = [NSURL fileURLWithPath: storePath];
NSError *error = nil;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
// Allow inferred migration from the original version of the application.
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
// Handle the error.
CLS_LOG(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
//Turn on complete file protection (encrypts files when phone is locked using device pin)
NSDictionary *fileAttributes = [NSDictionary dictionaryWithObject:NSFileProtectionComplete forKey:NSFileProtectionKey];
if(![[NSFileManager defaultManager] setAttributes:fileAttributes ofItemAtPath:storePath error:&error])
{
//handle error
}
return persistentStoreCoordinator;
}
When a user logs out, this is called to remove the model store:
- (NSPersistentStoreCoordinator *)resetPersistentStore
{
NSError *error = nil;
if ([persistentStoreCoordinator persistentStores] == nil)
return [self persistentStoreCoordinator];
[managedObjectContext release];
managedObjectContext = nil;
//If there are many stores, this could be an issue
NSPersistentStore *store = [[persistentStoreCoordinator persistentStores] lastObject];
if (![persistentStoreCoordinator removePersistentStore:store error:&error])
{
CLS_LOG(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
// Delete file
if ([[NSFileManager defaultManager] fileExistsAtPath:store.URL.path]) {
if (![[NSFileManager defaultManager] removeItemAtPath:store.URL.path error:&error])
{
CLS_LOG(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}
// Delete the reference to non-existing store
[persistentStoreCoordinator release];
persistentStoreCoordinator = nil;
NSPersistentStoreCoordinator *r = [self persistentStoreCoordinator];
return r;
}
My app has a single store, so I don't think NSPersistentStore *store = [[persistentStoreCoordinator persistentStores] lastObject]; would cause an issue.
A little late to respond, but I noticed that this error almost always occurred when our app had been pushed to the background.
When creating the persistentStoreCoordinator you may need to set the NSPersistentStoreFileProtectionKey option to NSFileProtectionCompleteUntilFirstUserAuthentication instead of NSFileProtectionComplete.
Note that this slightly elevates the security risk so you may want to consider if this is necessary in your app.
Are you sure that the database is correctly opened / closed at everytime? It can be a problem due to a file open while it was uncorrectly closed

NSManagedObjectModel mergedModelFromBundles error

I'm working with Core Data and having a lot of trouble's getting data into the database right off the start of my app.
Below is some of the code I've grabbed from a tutorial I followed.
The point where I get the SIGABRT is outlined below.
Any suggestions or help is appreciated
Thanks
//THIS FUNCTION IS CALLED AFTER MY APP DID FINISHING LOADING IN THE
// IN THE APP DELEGATE
-(void)loadData
{
NSManagedObjectContext *context = [self managedObjectContext];
NewModel *newModel = (NewModel *)[NSEntityDescription insertNewObjectForEntityForName:#"NewModel" inManagedObjectContext:context];
//ADD MORE DATA TO ENTITY
}
/**
Returns the managed object context for the application.
If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
*/
- (NSManagedObjectContext *) managedObjectContext {
if (managedObjectContext != nil) {
return managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator: coordinator];
}
else
{
NSLog(#"Error");
}
return managedObjectContext;
}
/**
Returns the managed object model for the application.
If the model doesn't already exist, it is created by merging all of the models found in the application bundle.
*/
- (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel != nil) {
return managedObjectModel;
}
/**********************************************************/
// SIGABRT HAPPENS IN THE NEXT LINE OF CODE
/**********************************************************/
managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
return managedObjectModel;
}
/**
Returns the persistent store coordinator for the application.
If the coordinator doesn't already exist, it is created and the application's store added to it.
*/
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSString *storePath = [ [self applicationDocumentsDirectory] stringByAppendingPathComponent:#"NewModel.db"];
NSURL *storeUrl = [NSURL fileURLWithPath:storePath];
// Put down default db if it doesn't already exist
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:storePath]) {
NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:#"LeagueModel" ofType:#"sqlite"];
if (defaultStorePath) {
[fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
}
}
NSError *error = nil;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return persistentStoreCoordinator;
}
/**
Returns the path to the application's Documents directory.
*/
- (NSString *)applicationDocumentsDirectory {
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}
if you check the apple's documentation:
mergedModelFromBundles:
Returns a model created by merging all the models found in given bundles.
+ (NSManagedObjectModel *)mergedModelFromBundles:(NSArray *)bundles
Parameters
***bundles***
An array of instances of NSBundle to search. If you specify nil, then the main bundle is searched.
***Return Value***
A model created by merging all the models found in bundles.
you are passing nil where you need to pass the array for bundles this is the reason for crash.

Resources