I am currently writing the next version of an app.
In the Old version, there was no CoreData sqlite
In the New version, we have a local CoreData sqlite database.
When I install the new version of the application from scratch, there is no problems, the store is there and I can query.
However, when I install the app on phone that has the previous version on it, my queries come back with no results.
When I look at the logs, there is nothing in the console, and no errors are returned.
#import "CoreDataHelper.h"
@implementation CoreDataHelper
@synthesize store = _store;
@synthesize coordinator = _coordinator;
#pragma mark -
#pragma mark - FILES
NSString *storeFileName = @"Reporting.sqlite";
#pragma mark -
#pragma mark - PATHS
- (NSString *)applicationDocumentsDirectory {
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}
- (NSURL *)applicationStoresDirectory {
NSURL *storesDirectory = [[NSURL fileURLWithPath:[self applicationDocumentsDirectory]]URLByAppendingPathComponent:@"Stores"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:[storesDirectory path]]) {
NSError *error = nil;
if ([fileManager createDirectoryAtURL:storesDirectory
withIntermediateDirectories:YES
attributes:nil
error:&error]) {
//File created
} else {
//Error
}
}
return storesDirectory;
}
- (NSURL *)storeURL {
return [[self applicationStoresDirectory] URLByAppendingPathComponent:storeFileName];
}
#pragma mark -
#pragma mark - SETUP
- (id)init {
if (self = [super init]) {
_model = [NSManagedObjectModel mergedModelFromBundles:nil];
_coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:_model];
_context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_context setPersistentStoreCoordinator:_coordinator];
}
return self;
}
- (void)loadStore {
if (_store) return; // Don't load store if it is already loaded
// to generate the database in the app launching comment next lines...
if(![self getFileExistence:storeFileName]){
// file URL in our bundle
NSURL *fileFromBundle = [[NSBundle mainBundle]URLForResource:@"FaultReporting" withExtension:@"sqlite"];
// Destination URL
NSURL *destinationURL = [[self applicationStoresDirectory] URLByAppendingPathComponent:@"FaultReporting.sqlite"];
// copy it over
[[NSFileManager defaultManager]copyItemAtURL:fileFromBundle toURL:destinationURL error:nil];
}
// end of comments
NSError *error = nil;
@try {
_store = [_coordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:[self storeURL]
options:@{ NSMigratePersistentStoresAutomaticallyOption: @(YES),
NSInferMappingModelAutomaticallyOption: @(YES)}
error:&error];
}
@catch (NSException *exception) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:[NSString stringWithFormat:@"Error: %@, %@",error, [error userInfo]] delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil, nil];
[alert show];
}
@finally {
//
}
}
Migrations happen in three steps: First, Core Data copies over all the objects from one data store to the next. Next, Core Data connects and relates all the objects according to the relationship mapping. Finally, enforce any data validations in the destination model.
The next time you need to store data, you should have a better idea of your options. Core Data is unnecessary for random pieces of unrelated data, but it's a perfect fit for a large, relational data set. The defaults system is ideal for small, random pieces of unrelated data, such as settings or the user's preferences.
Core Data can typically perform an automatic data migration, referred to as lightweight migration. Lightweight migration infers the migration from the differences between the source and the destination managed object models.
We perform heavyweight migration when we have either normalized or generalized our database. In such cases, lightweight migration won't help us. We will have to manually map attributes of the old data model to the new data model, and doing so is called heavyweight migration.
Su. Not sure if you did this but try the follwoing:
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
[[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];
NSError* error;
[managedObjectContext.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:self.storeUrl
options:options // this is required to migrate some core data model attributes
error:&error];
Basically have to tell it to use this migration thing in the options when you're setting it up.
I am not sure if this would apply to you or not, but I had a similar situation when upgrading from iOS 7 to iOS 8. In iOS 8 NSManagedObject
added a property for deleted
. I happened to have a property called deleted
on my managed object models. I had to change the name of my deleted column to something that didn't conflict with the new deleted property on NSManagedObject
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With