2010-06-11 15 views
19

J'utilise avec succès la migration automatique légère de Core Data. Cependant, quand une entité particulière est créée pendant une migration, je voudrais la peupler avec des données. Bien sûr, je pourrais vérifier si l'entité est vide à chaque démarrage de l'application, mais cela semble inefficace lorsque Core Data dispose d'une infrastructure de migration.Détection d'une migration de données de base légère

Est-il possible de détecter quand une migration légère se produit (éventuellement en utilisant KVO ou des notifications), ou cela nécessite-t-il l'implémentation de migrations standard?

J'ai essayé d'utiliser le NSPersistentStoreCoordinatorStoresDidChangeNotification, mais il ne se déclenche pas lorsque des migrations se produisent.

Répondre

54

Pour détecter si une migration est nécessaire, vérifiez si le modèle d'objet persistant géré de coordinateur du magasin est compatible avec les métadonnées du magasin existant (adapté de son Is Migration Necessary Apple):

NSError *error = nil; 
persistentStoreCoordinator = /* Persistent store coordinator */ ; 
NSURL *storeUrl = /* URL for the source store */ ; 

// Determine if a migration is needed 
NSDictionary *sourceMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType 
                          URL:storeUrl 
                         error:&error]; 
NSManagedObjectModel *destinationModel = [persistentStoreCoordinator managedObjectModel]; 
BOOL pscCompatibile = [destinationModel isConfiguration:nil compatibleWithStoreMetadata:sourceMetadata]; 
NSLog(@"Migration needed? %d", !pscCompatibile); 

Si pscCompatibile est NO, puis une migration devra avoir lieu. Examiner les changements d'entité, comparer la NSStoreModelVersionHashes clé dans le dictionnaire sourceMetadata au [destinationModel entities]:

NSSet *sourceEntities = [NSSet setWithArray:[(NSDictionary *)[sourceMetadata objectForKey:@"NSStoreModelVersionHashes"] allKeys]]; 
NSSet *destinationEntities = [NSSet setWithArray:[(NSDictionary *)[destinationModel entitiesByName] allKeys]]; 

// Entities that were added 
NSMutableSet *addedEntities = [NSMutableSet setWithSet:destinationEntities]; 
[addedEntities minusSet:sourceEntities]; 

// Entities that were removed 
NSMutableSet *removedEntities = [NSMutableSet setWithSet:sourceEntities]; 
[removedEntities minusSet:destinationEntities]; 

NSLog(@"Added entities: %@\nRemoved entities: %@", addedEntities, removedEntities); 
+1

+1 pour avoir partagé la deuxième partie de votre réponse. – cocoafan

+0

@hadronzoo il migre toujours comme je commence l'application ,, ne devrait-il pas être fait une seule fois? –

+0

@AhmedZ. non, il arrive juste une fois –

1

Qu'en est-il pour cette sous-classement NSManagedObject entité, puis remplaçant -awakeFromInsert :? Ou créez-vous cette entité dans d'autres parties de votre application?