2010-06-11 5 views
19

Sto utilizzando correttamente la migrazione leggera automatica dei dati di base. Tuttavia, quando una particolare entità viene creata durante una migrazione, mi piacerebbe popolarla con alcuni dati. Naturalmente potrei verificare se l'entità è vuota ogni volta che l'applicazione si avvia, ma ciò sembra inefficiente quando Core Data ha un framework di migrazione.Rilevamento di una migrazione leggera dei dati principali

È possibile rilevare quando si verifica una migrazione leggera (possibilmente utilizzando KVO o notifiche) oppure è necessario implementare migrazioni standard?

Ho provato a utilizzare NSPersistentStoreCoordinatorStoresDidChangeNotification, ma non si attiva quando si verificano migrazioni.

risposta

54

per rilevare se è necessaria una migrazione, verificare se il modello oggetto gestito la persistente del coordinatore negozio è compatibile con i metadati del negozio esistente (adattata da Apple Is Migration Necessary):

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); 

Se pscCompatibile è NO, poi una migrazione dovrà verificarsi. Per esaminare le modifiche di entità, confrontare la chiave NSStoreModelVersionHashes nel dizionario sourceMetadata al [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 per condividere la seconda parte della risposta. – cocoafan

+0

@hadronzoo sta migrando sempre all'avvio dell'applicazione, non dovrebbe essere fatto una sola volta? –

+0

@ AhmedZ. no succede solo una volta –

1

Che dire sottoclasse NSManagedObject per tale entità, e quindi ignorando -awakeFromInsert :? O stai creando questa entità in altre parti della tua app?