CoreData Migration Issues

I am currently writing the next version of the application.

In the old version there was no sqlite CoreData p>

In the new version, we have a local sqlite CoreData database.

When I install the new version of the application from scratch, there are no problems, there are in the store and I can request.

However, when I install the application on the phone with the previous version, my queries are returned without any results.

When I look at the logs, nothing happens 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 { // } } 
+6
source share
3 answers

Su. Not sure if you did this, but try the following:

  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 it needs to be said in order to use this migration thing in settings when you configure it.

+2
source

I'm not sure if this applies to you or not, but I had a similar situation when upgrading from iOS 7 to iOS 8. In iOS 8 NSManagedObject , a property for deleted added. I had a property called deleted on my managed object models. I had to change the name of my remote column to something that does not conflict with the new remote property on NSManagedObject .

+1
source

Could you confirm that you have completed all these steps?

Step 1: Add Framework

Click on the application’s landing page (in the left pane its top icon with the name of your application), then go to the “Phase Assembly” tab, then in “Linking binary files to libraries”, click the small “+” number and then find “CoreData.framework "and add it to your project

Then either import coredata for all the objects that need it:

 #import <CoreData/CoreData.h> 

or add import under general import to your .pch file:

 #ifdef __OBJC__ #import <UIKit/UIKit.h> #import <Foundation/Foundation.h> #import <CoreData/CoreData.h> #endif 

Step 2: add a data model

To add the .xcdatamodel file, right-click / right-click on your files in the right pane (for example, in the "Resources" folder for safe storage) and select "Add New File". Go to the tab “Master data” when choosing a file type, then click “Data Model”, give it a name and click “Next” and “Finish”, and it will add it to your project. When you click on this model object, you will see that the interface will add objects to your project with any relationships you want.


Step 3: Update Application Delegate

Add these objects to AppDelegate.h

  @property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel; @property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext; @property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator; - (NSURL *)applicationDocumentsDirectory; // nice to have to reference files for core data 

Synthesize previous objects in AppDelegate.m as follows:

 @synthesize managedObjectContext = _managedObjectContext; @synthesize managedObjectModel = _managedObjectModel; @synthesize persistentStoreCoordinator = _persistentStoreCoordinator; 

Then add these methods to AppDelegate.m (do not forget to specify the name of the model that you added at the points shown):

 - (void)saveContext{ NSError *error = nil; NSManagedObjectContext *managedObjectContext = self.managedObjectContext; if (managedObjectContext != nil) { if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } } } - (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 *modelURL = [[NSBundle mainBundle] URLForResource:@"NAMEOFYOURMODELHERE" withExtension:@"momd"]; _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; return _managedObjectModel; } - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (_persistentStoreCoordinator != nil) { return _persistentStoreCoordinator; } NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"NAMEOFYOURMODELHERE.sqlite"]; 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; } #pragma mark - Application Documents directory // Returns the URL to the application Documents directory. - (NSURL *)applicationDocumentsDirectory{ return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; } 

Step 4: Get Data Objects in ViewControllers Where You Need Data

in ViewController.h

 @property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; 

In ViewController.m

 @synthesize managedObjectContext = _managedObjectContext; 

In the AppDelegate or class where the ViewController is created, set the managedObjectContext to the same as the AppDelegate

 ViewController.managedObjectContext = self.managedObjectContext; 

If you want the viewcontroller using Core Data to be a FetchedResultsController, you need to make sure that this material is in your ViewController.h

 @interface ViewController : UIViewController <NSFetchedResultsControllerDelegate> { NSFetchedResultsController *fetchedResultsController; NSManagedObjectContext *managedObjectContext; } @property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController; 

And this is in ViewController.m

 @synthesize fetchedResultsController, managedObjectContext; 

Link: How to add Core Data to an existing project in Xcode

Hope it sheds light on your problem.

+1
source

Source: https://habr.com/ru/post/977889/


All Articles