Mise en œuvre de la «migration automatique légère» pour les données de base (iPhone)

Je voudrais que mon application puisse effectuer une migration automatique légère lorsque j’ajoute de nouveaux atsortingbuts à mon modèle de données principal.

Dans le guide d’Apple, c’est la seule information sur le sujet que j’ai pu trouver:

Migration automatique légère

Pour demander une migration automatique légère, vous définissez les indicateurs appropriés dans le dictionnaire d’options que vous transmettez dans addPersistentStoreWithType: configuration: URL: options: error :. Vous devez définir les valeurs correspondant aux clés NSMigratePersistentStoresAutomaticallyOption et NSInferMappingModelAutomaticallyOption sur YES:

NSError *error; NSURL *storeURL = ; NSPersistentStoreCoordinator *psc = ; NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; if (![psc addPersistentStoreWithType: configuration: URL:storeURL options:options error:&error]) { // Handle the error. } 

Mon NSPersistentStoreCoordinator est initialisé de cette manière:

 - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (persistentStoreCoordinator != nil) { return persistentStoreCoordinator; } NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] ssortingngByAppendingPathComponent: @"FC.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; } 

J’ai du mal à voir où et comment je devrais append le code Apple pour que la migration automatique légère fonctionne?

C’est ce que j’ai fait pour rendre la migration automatique légère (Source: http://brainwashinc.wordpress.com/2010/01/18/iphone-coredata-automatic-light-migration/ )

1. Définissez les options du magasin persistant pour la migration automatique dans le délégué d’application.

Changez votre création persistentStoreCoordinator en ceci (remplacez YOURDB):

 - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (persistentStoreCoordinator != nil) { return persistentStoreCoordinator; } NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] ssortingngByAppendingPathComponent: @"YOURDB.sqlite"]]; // handle db upgrade NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; NSError *error = nil; persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]]; if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) { // Handle error } return persistentStoreCoordinator; } 

2. Version de votre modèle de données et modifiez le nouveau fichier.

Sélectionnez votre fichier xcdatamodel Conception -> Modèle de données -> Ajouter la version du modèle (développez votre élément xcdatamodeld) Sélectionnez le fichier «2 ″ (ou ultérieur), Conception -> Modèle de données -> Définir la version actuelle (modifiez cette version)

3. Spécifiez la ressource momd dans le délégué d’application.

Changez votre implémentation managedObjectModel en ceci (remplacez YOURDB)

 - (NSManagedObjectModel *)managedObjectModel { if (managedObjectModel != nil) { return managedObjectModel; } NSSsortingng *path = [[NSBundle mainBundle] pathForResource:@"YOURDB" ofType:@"momd"]; NSURL *momURL = [NSURL fileURLWithPath:path]; managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL]; return managedObjectModel; } 

Au début, la solution ci-dessus ne fonctionnait pas pour moi. Le managedObjectModel renvoyé était 0x0. Je pense que c’est parce que j’ai renommé les noms de fichiers des différents fichiers de modèle. Si vous suivez les instructions ci-dessus à la lettre alors tout fonctionne.

Cependant, si vous modifiez les noms de fichiers de modèle, vous pouvez sélectionner manuellement le fichier de modèle “actuel”: Supposons que votre fichier de modèle d’origine était MYMODEL.xcdatamodel, après avoir effectué l’étape d’ajout de modèle ci-dessus, vous obtenez un répertoire MY. MYMODEL.xcdatamodel et MYMODEL 2.xcdatamodel renomment le nouveau fichier de modèle en fonction de ce que vous voulez, par exemple, disons que vous avez supprimé l’espace de MYMODEL2.xcdatamodel et modifié son contenu. Maintenant, dans le code ci-dessus faire

 NSSsortingng *path = [mainBundle pathForResource:@"MYMODEL2" ofType:@"mom" inDirectory:@"MYMODEL.momd"]; 

Je pense que cela ajoute à la dernière réponse.

J’ai trouvé l’utilisation de la ressource bundle et des noms de fichiers .sqlite vraiment déroutante au début. Le nom de ressource du bundle change-t-il avec le changement de version? Le nom de domaine .sqlite change-t-il? Ma migration fonctionne maintenant et j’ai appris que le nom du modèle de bundle fait référence au nom du répertoire / dossier dans XCode contenant tous les modèles, pas le nom des versions de modèle dans ce répertoire.

Lorsque vous donnez un nom modelResource à:

 NSURL *modelURL = [[NSBundle mainBundle] URLForResource:modelResource withExtension:@"momd"]; NSManagedObjectModel *theManagedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; 

Ce nom modelResource est le répertoire / dossier pour les modèles dans Xcode.

Quand tu fais:

  NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:storeFileName]; NSError *error = nil; if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) { // handle error } 

Le storeFileName est le nom de votre fichier .sqlite dans le dossier / répertoire Documents (ce n’est pas dans le bundle).

De plus, lorsque vous migrez d’une version de modèle vers une autre version du modèle, le nom du fichier .sqlite rest le même par défaut.

Oscar, en réponse à votre problème, j’ai trouvé la même chose au départ. Je suggère de supprimer et de rappend le nouveau fichier .xcdatamodeld à votre projet, puis de le reconstruire. J’espère que cela pourra aider!

Swift 3 Solution

1. Définissez les options du magasin persistant pour la migration automatique dans le délégué d’application.

Changez votre création persistentStoreCoordinator en ceci (remplacez SingleViewCoreData.sqlite):

 lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = { let coordinator: NSPersistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel) let url = self.applicationDocumentsDirectory.appendingPathComponent("SingleViewCoreData.sqlite") let options = [ NSMigratePersistentStoresAutomaticallyOption : Int(true), NSInferMappingModelAutomaticallyOption : Int(true) ] do { try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: options) } catch { print(error) } return coordinator }() 

2. Version de votre modèle de données et modifiez le nouveau fichier.

Sélectionnez votre éditeur de fichier xcdatamodel> Ajouter une version de modèle – ajoutez un nom à votre nouveau modèle