ios - guide - iPhone Core Data "Migración liviana automática"
ios frameworks (9)
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 cacao 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 cacao 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 = <869d4b20 088e5c44 5c345006 87d245cd 67ab9bc4 14cadf45 180251e9 f741a98f>; Tienda = <47c250f4 895e6fd1 5033ab42 22d2d493 7819ba75 3c0acffc 2dc54515 8deeed7a>; }; 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:
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) .Salvar.
Seleccione su nuevo
.xcdatamodel
y realice el cambio que desee emplear de acuerdo con la documentación de Migración Ligera .Salvar.
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.Salvar.
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ámetrooptions
, reemplacenil
con el siguiente código:[NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]
Ejecuta tu aplicación. Si no se produce un bloqueo, es probable que hayas migrado correctamente :)
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.
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
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...
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";
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):
- 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
) - Salvar
- Haz tu cambio
- Salvar
- 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.
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.
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 aumentará 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.
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.