Trabajar con datos básicos control de versiones y migraciones ligeras

Después de leer Primeros pasos con Core Data, nos encontramos iluminados en la forma en que Core Data funciona y cómo puede ayudarnos a desarrollar aplicaciones ricas en datos. Sin embargo, la superficie solo se rasguñó, y en algunas aplicaciones podría preguntarse cómo implementar una determinada pieza de funcionalidad..

Mi experiencia con Core Data

En los últimos meses, he estado trabajando con Core Data en un proyecto de mascotas. Es una aplicación para extraer datos de una API de servicio remoto, almacenar los datos en Core Data y mostrarlos en una colección de UITableViews. En el transcurso del desarrollo, ha pasado de un almacén de datos basado en la Lista de propiedades (* shudder *) a un almacén SQL de Core Data. Después de tres reconstrucciones completas y muchas largas noches de depuración, mi aplicación finalmente se ha convertido en un proyecto rápido, sin interrupciones y sin fugas de memoria. Para mí, el uso de Core Data ha hecho de mi aplicación lo que estaba destinado a ser, y compartiré mucho de lo que aprendí con usted en este y en futuros artículos..

Para este artículo, nos basaremos en la aplicación LapTimer anterior y demostraremos realizar migraciones ligeras.

Cambios de esquema, control de versiones y migraciones

Cuando esté desarrollando una aplicación, casi nunca obtendrá el esquema correctamente la primera vez. Por lo tanto, Core Data admite el control de versiones de esquemas y la migración de datos. Esto le permite definir una nueva versión del esquema de Core Data agregando un nuevo atributo o entidad a la tienda. Luego define cómo la tienda tiene que migrar de un cambio a otro.

Creando un nuevo xcdatamodel

Core Data maneja las versiones del esquema de manera diferente a otros marcos que podrías haber usado en el pasado. Cuando pasa por el desarrollo y requiere un nuevo atributo o entidad, el proceso de agregarlos es mediante la creación de un nuevo archivo xcdatamodel para su aplicación. Este nuevo archivo será versionado, tendrá un número incremental en el nombre del archivo y es distinto de las versiones anteriores del esquema. En la aplicación LapTimer, cree la nueva versión del modelo de datos. Haga clic en el archivo xcdatamodel en su aplicación y luego navegue hasta el elemento del menú en: Diseño> Modelo de datos> Agregar versión de modelo.

Ahora tendrá un árbol xcdatamodel, siendo el padre un nuevo archivo xcdatamodel, con una nueva versión del esquema indicada por el número incremental. Además, hay una marca verde contra el esquema anterior. Esto indica qué esquema está activo y la aplicación que utilizará. Es importante tener en cuenta que elegir la nueva versión de inmediato puede causar algunos problemas en el desarrollo. Dado que aún no hemos configurado una migración para este nuevo esquema, si tuviéramos que hacer que el nuevo esquema fuera el activo, entonces el Simulador o el Dispositivo generarán un error y se bloquearán durante el arranque. Como demostración, observe el error a continuación, es común para lo que las personas encuentran en su primer intento:

Básicamente solo dice "Oye, has cambiado el esquema de base de datos activo y estoy atascado en una versión anterior". Esto evita que la aplicación entre conflictos y errores con el cambio del esquema del Core Data Store. Hace una comparación basada en los detalles del esquema con el que la tienda está operando. Si se le da una nueva versión de esquema para usar pero no coincide con lo que se ha configurado o migrado, entonces aparece este error..

Entonces, ¿cómo podemos superar esto? Bueno, hay dos opciones:

  1. Si la aplicación está en desarrollo y no le importa ningún dato en la aplicación, simplemente elimine la aplicación del dispositivo y vuelva a instalarla. Se eliminará la tienda y su contenido, pero se creará la aplicación con el nuevo esquema. Esta es solo una opción en desarrollo..
  2. Use una migración ligera para ocuparse automáticamente de pequeños cambios de esquema cada vez que los realice. Esto se limita a solo unas pocas migraciones que se detallan a continuación.

Migración ligera

Esta es una función fácil de usar y automática de Core Data, pero se limita a migraciones simples, por lo que es liviana. Solo puede utilizar este método si los cambios se encuentran entre los siguientes:

  • Agregar un nuevo atributo / propiedad a una entidad.
  • Renombrar una entidad o un atributo / propiedad si se da el 'Renombrado del identificador'.
  • Cambiar un atributo / propiedad a opcional o no opcional, ya sea que requiera un valor en la creación.

Nota: antes de comenzar, si está trabajando en el proyecto LapTimer, tendrá que crear el proyecto antes de que comencemos. Asegúrese de que xcdatamodel activo sea la primera versión con la que se creó la aplicación. De esta forma podrás ver el trabajo de migración..

Como demostración, la aplicación LapTimer va a tener la entidad de evento cambiada a Lap. Con esto también tenemos que actualizar las clases Event.h y Event.m y cualquier ocurrencia de aquellas en la aplicación. Con un par de ingeniosas características de Xcode, esto es indoloro..

Entonces, en la nueva versión de xcdatamodel que creamos anteriormente, haré el cambio simplemente cambiando los valores en el panel de detalles de la entidad. Ahora necesitamos configurar el 'Renombrar identificador' a Evento. Entonces, en el mismo panel, haga clic en la llave inglesa / llave inglesa e ingrese "Evento" en el campo de cambio de nombre del identificador, así:

El siguiente paso es decirle a Core Data que puede realizar migraciones ligeras en el arranque. Haciendo referencia a la aplicación LapTimer, en el archivo LapTimerAppDelegate.m tendremos que agregar un poco de código al método - (NSPersistentStoreCoordinator *) persistentStoreCoordinator:

 - (NSPersistentStoreCoordinator *) persistentStoreCoordinator if (persistentStoreCoordinator! = Nil) return persistentStoreCoordinator;  NSURL * storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @ "LapTimer.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 settings: nil URL: storeUrl opciones: error de opciones: & error]) / * Reemplace esta implementación con el código para manejar el error adecuadamente. abort () hace que la aplicación genere un registro de bloqueo y finalice. No debe usar esta función en una aplicación de envío, aunque puede ser útil durante el desarrollo. Si no es posible recuperarse del error, muestre un panel de alerta que indique al usuario que abandone la aplicación presionando el botón Inicio. Las razones típicas de un error aquí incluyen: * No se puede acceder al almacén persistente * El esquema para el almacén persistente es incompatible con el modelo de objeto administrado actual. Compruebe el mensaje de error para determinar cuál fue el problema real. * / NSLog (@ "Error no resuelto% @,% @", error, [error userInfo]); abortar();  return persistentStoreCoordinator;  

El código agregado fueron las opciones NSDictionary que le indicarán a Core Data que realice migraciones automáticas.

Casi terminamos. El siguiente paso es cambiar los archivos de clase para que la entidad Evento refleje el nuevo nombre. Para hacer esto usamos mi función favorita de Xcode, la función Refactor. Como lo indica el nombre, esta función se refactorizará y realizará una Búsqueda y reemplazo más avanzados en su proyecto para situaciones como estas.

Para hacer esto, deberá abrir Event.m y seleccionar el texto 'Event' en ese archivo. Luego vaya a: Editar> Refactor (Cmd + Shift + J). Arriba abrirá una ventana con opciones y campos como la siguiente captura de pantalla. Ingrese la palabra Vuelta en el campo 'Evento a'. Haga clic en vista previa y obtendrá la salida de todos los cambios:

Si desea ver qué hará esto, haga clic en uno de los archivos en el panel de resultados y le mostrará los detalles de lo que cambiará. También cambiará el nombre de los archivos Event.h y Event.m para nosotros. Solo para tener en cuenta, los anteriores archivos xcdatamodel con la clase NSManagedObject particular que se reemplaza tendrán un ligero cambio. Cambiará el nombre de la clase de la entidad, no su nombre de la entidad, por lo que si un dispositivo tiene que pasar por la migración, todavía puede usar la clase de entidad NSManagedObject y los métodos relacionados.

Pulse aplicar. Eso es. Como medida de seguridad, también tomará una instantánea, otra gran característica de XCode. Así que si todo va mal, puedes volver a la instantánea anterior, como Time Machine, pero sin todas las estrellas y la interfaz de usuario de la galaxia swirly..

Desafortunadamente, eso no capta todos los cambios necesarios. Todavía hay algunos bits de la aplicación LapTimer que hacen referencia al Evento. Así que un rápido Buscar y reemplazar está en orden. Ir: Editar> Buscar en proyecto. Con la nueva ventana ingrese Evento como hallazgo y Vuelta como reemplazo. Desmarque 'Ignorar caso', ya que solo queremos retomar el uso estricto de la capitalización del hallazgo. Luego cambie el menú desplegable donde se selecciona 'Contiene' y seleccione 'Palabras completas' en su lugar. Esto reducirá el hallazgo a exactamente lo que necesitamos.

Haga clic en buscar. Revise los cambios. Si todo ha ido bien, entonces realice el reemplazo!

Cambiando el esquema activo

Así que hemos creado una nueva versión del esquema, hemos realizado algunas modificaciones y ahora es el momento de incluir la aplicación en el nuevo esquema..

Nada complicado aquí. Seleccione el nuevo esquema que desea establecer como activo y navegue a: Diseño> Modelo de datos> Establecer versión actual. La marca verde se moverá al nuevo esquema y estará listo para comenzar..

Generar y ejecutar la aplicación. Todos deben estar bien y la aplicación debe abrir, migrar y ejecutar. No notará esta migración en absoluto, ni siquiera una salida del depurador. Pero el hecho de que el código se esté ejecutando y funcione es una prueba de que ha migrado.

Resumen

Así que la aplicación ahora tiene un nombre de entidad modificado. Esto puede suceder de vez en cuando en el desarrollo de cualquier aplicación. Puede agregar nuevas propiedades con este método de migración ligero con este mismo proceso.

Si necesita cambiar el tipo de una propiedad o hacer cambios más avanzados, entonces deberá sumergirse en la migración de Objetos Modelo de Mapeo. Este es un método más avanzado de lo que realizamos, que requiere configuraciones y código adicionales. La documentación de Apple iOS tiene una muy buena ejecución de este proceso de migración avanzada.