Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CoreData migration issues

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 {
        //
    }

}
like image 537
Jason Rogers Avatar asked Nov 07 '14 17:11

Jason Rogers


People also ask

What is migration in Core Data?

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.

Should I use Core Data?

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.

What is lightweight migration?

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.

What is heavy weight migration?

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.


2 Answers

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.

like image 183
angryCutlet Avatar answered Sep 18 '22 22:09

angryCutlet


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.

like image 28
Stephen Johnson Avatar answered Sep 17 '22 22:09

Stephen Johnson