2011-06-29 14 views
12

Tengo 2 modelos de objetos en Core Data (por ejemplo, v1 y v2). Esta migración es elegible para una migración ligera. Ahora, deseo ejecutar código personalizado después de la migración, pero solo cuando la migración sea de v1 a v2. Más adelante, si presento v3, no quiero que se ejecute el código personalizado.Ejecución de código personalizado después de la migración ligera de una versión particular

¿Hay alguna manera de hacerlo?

Gracias de antemano, Anupam

+0

Puede alguien por favor me ayude a cabo? –

+0

La última vez que quería hacer algo así terminé simplemente con una migración personalizada ... pero a menudo la mayor parte de una migración podría ser ligera si solo se pudiera incluir ese paso personalizado final, así que me gusta la pregunta. Bounty se ha agregado a esta pregunta para llamar más la atención y ver si alguien tiene una buena respuesta a esto. –

Respuesta

1

Puede haber una mejor manera, comprar esto debería funcionar:

Realizar un seguimiento de la versión DB, manteniendo una entidad en la base de datos denominada "información" y tienen una propiedad llamada "CoreDataVersion".

Después de que el código de migración finalice agregue código para verificar el número de versión en los datos del núcleo.

Si el valor de "CoreDataVersion" es "v1" y su aplicación ahora está en "v2" (esto puede codificarse con cada versión), ejecute el código personalizado adicional y luego vuelva a escribir la nueva versión en la base de datos.

Si ya tiene "v1" publicado para los usuarios, solo diga que si no hay "CoreDataVersion" en la base de datos, entonces es "v1".

1
- (void) _performMaintanaceUpdate:(NSUInteger) newVersion oldVersion:(NSUInteger) oldVersion { 
      if (newVersion>=1020500 && oldVersion < 1020500) { 
       NSString *storePath = [[PreferenceDataModel getDataPath] stringByAppendingPathComponent: @"wcal.sqlite"]; 
       NSFileManager *fileManager = [NSFileManager defaultManager]; 
       if ([fileManager fileExistsAtPath:storePath]) { 
         [fileManager removeItemAtPath:storePath error:NULL]; 
       } 
       [PreferenceDataModel setVersionOfLastMaintanace:newVersion]; 
      } 
} 

(void) _checkAndPerformMaintenance{ 
    NSString* strVersion = [PreferenceDataModel getApplicationVersion]; 
    //legal version is xx.xx.xx where x is a dec digit 1.2 or 1.2.33 is legit 
    NSUInteger ver = 0; 
    NSUInteger finalVer = 0; 
    int t = 3; 

    for (int i=0; i<[strVersion length]; i++) { 
     char c = [strVersion characterAtIndex:i]; 
     if (isdigit(c)) { 
      ver*=10; 
      ver+=c - 48; 
     } 
     else { 
      finalVer+= ver * pow(100, t--); 
      ver = 0; 
     } 
    } 
    finalVer+= ver * pow(100, t); 
    [self _performMaintanaceUpdate:finalVer oldVersion:[PreferenceDataModel getVersionOfLastMaintanace]]; 
} 

y esta es la forma de recuperar la versión aplicaciones

+(NSString *) getApplicationVersion { 
    return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; 
} 
1

Antes de crear el almacén persistente que hace la migración automática, determinar si va a migrar a la versión 2. Si va a estar, establece una bandera para hacer tus cambios luego de que ocurra la migración.

Para determinar lo que va a migrar desde, haga lo siguiente:

NSString *path = [[NSBundle mainBundle] pathForResource:@"Model" ofType:@"momd"]; 
NSURL *momURL = [NSURL fileURLWithPath:path]; 
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL]; 
NSString *version = [managedObjectModel.versionIdentifiers anyObject]; 

Los identificadores de versión se encuentran en Xcode.

10

Aquí es cómo manejar esta situación, básicamente, mediante el uso de metadatos de la tienda, según lo sugerido por los ingenieros de Apple en la WWDC 2010:

  • abrir la tienda (con las opciones de migración)
  • Comprobar metadatos de clave personalizada , p.ej "DonePostProcessing"
  • Hacer postprocesamiento ...
    • pueblan derivada atributos
    • insertar o eliminar objetos
    • tienda conjunto de metadatos (“DonePostProcessing” = SI)
  • Guardar cambios y metadatos

Más o menos, algo así como



- (void)loadStoreWithMigration:(NSURL *)url { 
    ... 

    store = [psc addPersistentStoreWithType: NSSQLiteStoreType configuration: nil URL: url options: opts error: &err]; 

    m = [store metadata]; 
    key = @”DonePostProcessing”; 
    if (m && ([[m objectForKey: key] integerValue] < 2)){ 
     [self doPostProcessingInContext: context]; 
     m2 = [[m mutableCopy] autorelease]; 
     [m2 setObject: [NSNumber numberWithInteger: 2] forKey: key]; 
     [store setMetadata: m2]; 

     ok = [context save:&err]; 
    } 

} 
+0

Esta es una solución perfecta para mí, ya que tengo un campo calculado que necesita actualizarse cada vez que cambio el algoritmo. ¡Gracias! – phatmann

0

Otra solución que ha funcionado bien para mí:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
    NSInteger currVersion = [defaults integerForKey:@"dataModelVersion"]; 
    NSString *version = [managedObjectModel.versionIdentifiers anyObject]; 
    if (currVersion == 0) { 
     [defaults setInteger:[version integerValue] forKey:@"dataModelVersion"]; 
    } 
    else if (currVersion < [version integerValue]) { 
     NSLog(@"Migration Code"); 
     [defaults setInteger:[version integerValue] forKey:@"dataModelVersion"]; 
    } 
Cuestiones relacionadas