iPhone Core Data “Migración liviana automática”

Estoy intentando actualizar una aplicación que implementa un almacén de datos central. Estoy agregando un atributo a una de las entidades.

Agregué el siguiente código a mi clase de delegado:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (persistentStoreCoordinator != nil) { return persistentStoreCoordinator; } NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"Shoppee.sqlite"]]; NSError *error = nil; persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) { NSLog(@"Error: %@",error); NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } return persistentStoreCoordinator; } 

Esto era de la siguiente URL: Doc

Obtengo el siguiente error al ejecutar el código:

2009-12-01 20: 04: 22.877

Shoppee [25633: 207] Error: error

Dominio = NSCocoaErrorDomain Code = 134130

UserInfo = 0x1624d20 “No se pudo completar la operación. (Error de cocoa 134130.)” 2009-12-01 20: 04: 22.879 Shoppee [25633: 207] Error no resuelto Error Domain = NSCocoaErrorDomain Code = 134130 UserInfo = 0x1624d20 “La operación no pudo ser completado. (Error de cocoa 134130.) “, {URL = file: // localhost / Users / Eric / Library / Application% 20Support / iPhone% 20Simulator / User / Applications / A8A8FB73-9AB9-4EB7-8F83-82F5B4467AF1 / Documents / MyApp .sqlite; metadata = {NSPersistenceFrameworkVersion = 241; NSStoreModelVersionHashes = {Item = ; Tienda = ; }; NSStoreModelVersionHashesVersion = 3; NSStoreModelVersionIdentifiers = (); NSStoreType = SQLite; NSStoreUUID = “8DC65301-3BC5-42BE-80B8-E44577B8F8E1”; }; reason = “No se puede encontrar el modelo para el almacén de origen”; }

Parece que de alguna manera necesito incluir el modelo de datos original, pero no estoy seguro de cómo hacerlo. ¿Alguna sugerencia?

Para recapitular / guía completa:

  1. Antes de realizar cualquier cambio, crea una nueva versión de modelo.

    En Xcode 4: Seleccione su .xcdatamodel -> Editor -> Agregar versión de modelo.

    En Xcode 3: Diseño -> Modelo de datos -> Agregar versión de modelo.

    Verá que se crea un nuevo .xcdatamodel en su carpeta .xcdatamodeld (que también se crea si no tiene ninguno) .

  2. Salvar.

  3. Seleccione su nuevo .xcdatamodel y realice el cambio que desee emplear de acuerdo con la documentación de Migración Ligera .

  4. Salvar.

  5. Establezca el esquema actual / activo en el esquema recién creado.

    Con la carpeta .xcdatamodeld seleccionada:

    En Xcode 4: barra lateral Utilidades -> Inspector de archivos -> Modelo de datos básicos versionado -> Seleccione el nuevo esquema.

    En Xcode 3: Diseño> Modelo de datos> Establecer versión actual.

    La marca verde en el icono .xcdatamodel se moverá al nuevo esquema.

  6. Salvar.

  7. Implemente el código necesario para realizar la migración en tiempo de ejecución.

    Donde se crea su NSPersistentStoreCoordinator (generalmente la clase AppDelegate), para el parámetro options , reemplace nil con el siguiente código:

     [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil] 
  8. Ejecuta tu aplicación. Si no se produce un locking, es probable que hayas migrado correctamente 🙂

  9. Cuando haya migrado correctamente, el código de migración (paso 7) puede eliminarse. (Depende del desarrollador determinar cuándo se puede considerar que los usuarios de una aplicación publicada migraron).

IMPORTANTE: No elimine las versiones / esquemas del modelo anterior. Core Data necesita la versión anterior para migrar a la nueva versión.

Me lo imaginé.

Diseño> Modelo de datos> Agregar versión de modelo

Para los Googlers otra vez, esto es lo que debes hacer (suponiendo que ya hayas configurado la migración ligera):

  1. Antes de realizar cambios, haga Diseño -> Modelo de datos -> Agregar versión modelo (verá que se crea un nuevo .xcdatamodel en su carpeta .xcdatamodeld )
  2. Salvar
  3. Haz tu cambio
  4. Salvar
  5. Ejecutar aplicación

El paso # 1 es crucial para hacer que esto funcione. Me encontré con este problema porque había seguido estos pasos para agregar un nuevo campo. Eso funciono. Agregué un segundo campo nuevo, pero me olvidé de “Agregar versión de modelo” y las cosas explotaron.

También para googlers. Regla simple, nunca elimine / edite ninguna versión numerada anterior. Cuando agregue la versión del modelo, el sufijo numérico boostá como 2..3..4, lo que significa que 2 es el 3 más antiguo, etc., pero el actual para editar es la versión no numerada.

No elimine las versiones de modelos anteriores como usuarios con db anterior, ya que una versión de modelo anterior no podrá migrar a su último modelo de base de datos sin comparar los esquemas anteriores y anteriores.

Solo una nota para aquellos que se encuentran con este Google, parece que incluso con la migración automática (mágica), aún necesita crear una versión de su tienda original y una nueva, y establecer la nueva como la versión actual.

Hasta ahora solo veo cómo evitar el mensaje de error.

¿Pero cómo lo arreglamos, en caso de que ya lo hayamos estropeado?

La siguiente solución solucionó el problema, pero perderá los datos en el DB:

Elimine / cambie el nombre del archivo sqlite de la aplicación desplegada / instalada.
Los archivos nombran una ubicación se dan directamente después del mensaje de error. p.ej:

reason = No se puede encontrar el modelo para el almacén de origen}, {
URL = “file: //localhost/Users/yourName/Library/Application%20Support/iPhone%20Simulator/4.3/Applications/62F342D4-F007-4F6F-96D2-68F902D3719A/Documents/Locations.sqlite”;

Algo a tener en cuenta cuando se realiza una migración ligera:

Si planea cambiar el nombre / modificar atributos, recuerde establecer el valor de “Renombrar ID” en el modelo nuevo o antiguo. Para usar el propio ejemplo de Apple, en XCode 4.3, seleccione paintColor en el nuevo modelo> cambie al Inspector de modelo de datos> Establezca el campo “Renombrar ID” en Color en la sección “Control de versiones”. Para mí, el hecho de no hacer este paso llevó a un error de tiempo de ejecución. Este mismo error también se trata aquí . Como nuevo usuario, no puedo publicar imágenes, así que aquí hay un enlace imgur (no spam, en realidad).

  (Cocoa error 134140.)" UserInfo=0x622b350 {reason=Can't find or automatically infer mapping model for migration 

También puede obtener este error cuando realiza un cambio en el modelo de datos y se ejecuta en una aplicación instalada que tiene una versión diferente del archivo sqlite. En este caso, simplemente elimine la aplicación instalada y vuelva a ejecutarla.

En caso de que alguien se encuentre con este escenario y ninguno de los anteriores funciona … Estaba borrando mi aplicación del simulador, limpiando, etc., pero nada funcionaría. Tenía que ir al directorio del simulador y registrar manualmente el archivo .sqlite para que la aplicación vuelva a funcionar. Ninguna pista…