¿Cómo creo una database sqlite para usarla con Core Data?

Mi objective es crear una database sqlite y completarla con datos (probablemente más de 1000 filas) y usar esta database para cargar previamente los datos básicos y llenar una vista de tabla.

Hasta ahora tengo la vista de tabla trabajando con Core Data, Managed Object Models. Puedo agregar elementos y eliminar elementos, básicamente tengo la plantilla Master-Detail funcionando pero con mi propio model.

La pregunta: ¿Cómo creo una database sqlite en el formatting correcto para usar con Core Data?

Lo he hecho con éxito utilizando bases de datos y tutoriales de libros provistos de sql. Lo que noté es que la tabla 'fugitivo' (por ejemplo) en mi tutorial está escrita 'ZFUGITIVE' en la database sqlite proporcionada. Todas sus columnas tienen la 'Z' anexa al frente ('ZFUGITIVEID', 'ZNAME' …) y existen tres columnas adicionales ('Z_PK', 'Z_ENT', 'Z_OPT') que no están incluidas en el administrador model de object (.xcdatamodeld). Además de los nombres de todas las mayúsculas y las columnas adicionales, también veo (en este .sqlite db que viene con un tutorial) que hay dos tablas adicionales 'Z_PRIMARYKEY' y 'Z_METADATA'.

Estoy familiarizado con los commands de terminal sqlite y puedo crear una database, pero no tiene el formatting correcto, filas adicionales o tablas extra con metadatos. Lo que hice como un experimento fue tomar la tabla de database Fugitive sqlite anterior y agregarle otra tabla. Al principio lo llamé tabla 'cosa' con columnas 'thingID' y 'título'. Creé el object administrado y lo conecté a mi vista de tabla. No pude por la vida de mí get los datos para precargar en datos centrales / mi vista de tabla. Recibí No hay posts de error, simplemente no cargaba datos (Me permitía agregar y eliminar elementos nuevos al igual que la plantilla Master-Detail).

Entonces cambié el nombre de la tabla 'cosa' por 'ZTHING' con columnas ('Z_PK', 'Z_ENT', 'Z_OPT', 'ZTHINGID' y 'ZTITLE') y ahora obtengo el siguiente post de error. Sé que me dice que he creado mi tabla de manera incorrecta, pero no puedo encontrar documentation sobre cómo crearla correctamente. Por favor ayuda.

Aquí está el error de bocina que básicamente indica que el número de versión registrado en la tabla Z_METADATA (columna Z_UUID) es incorrecto: [O eso creo]

Unresolved error Error Domain=NSCocoaErrorDomain Code=134100 "The operation couldn't be completed. (Cocoa error 134100.)" UserInfo=0x5b489c0 {metadata=<CFBasicHash 0x5b4e960 [0x2651380]>{type = immutable dict, count = 7, entries => 2 : <CFString 0x5b4ea40 [0x2651380]>{contents = "NSStoreModelVersionIdentifiers"} = <CFArray 0x5b4eb10 [0x2651380]>{type = immutable, count = 0, values = ()} 4 : <CFString 0x5b4ea90 [0x2651380]>{contents = "NSPersistenceFrameworkVersion"} = <CFNumber 0x5b4e530 [0x2651380]>{value = +248, type = kCFNumberSInt64Type} 6 : <CFString 0x5b4eac0 [0x2651380]>{contents = "NSStoreModelVersionHashes"} = <CFBasicHash 0x5b4eba0 [0x2651380]>{type = immutable dict, count = 1, entries => 1 : <CFString 0x5b4eb30 [0x2651380]>{contents = "Fugitive"} = <CFData 0x5b4eb50 [0x2651380]>{length = 32, capacity = 32, bytes = 0xe33370b6e7ca3101f91d25951e8bfe01 ... 9e50237bb313d390} } 7 : <CFString 0x1ee464 [0x2651380]>{contents = "NSStoreUUID"} = <CFString 0x5b4e850 [0x2651380]>{contents = "E711F65F-3C5A-4889-872B-6541E4B2863A"} 8 : <CFString 0x1ee324 [0x2651380]>{contents = "NSStoreType"} = <CFString 0x1ee2e4 [0x2651380]>{contents = "SQLite"} 9 : <CFString 0x5b4ea10 [0x2651380]>{contents = "NSStoreModelVersionHashesVersion"} = <CFNumber 0x5d0b520 [0x2651380]>{value = +3, type = kCFNumberSInt32Type} 10 : <CFString 0x5b4eaf0 [0x2651380]>{contents = "_NSAutoVacuumLevel"} = <CFString 0x5b4ebf0 [0x2651380]>{contents = "2"} } , reason=The model used to open the store is incompatible with the one used to create the store}, { metadata = { NSPersistenceFrameworkVersion = 248; NSStoreModelVersionHashes = { Fugitive = <e33370b6 e7ca3101 f91d2595 1e8bfe01 3e7fb4de 6ef2a31d 9e50237b b313d390>; }; NSStoreModelVersionHashesVersion = 3; NSStoreModelVersionIdentifiers = ( ); NSStoreType = SQLite; NSStoreUUID = "E711F65F-3C5A-4889-872B-6541E4B2863A"; "_NSAutoVacuumLevel" = 2; }; reason = "The model used to open the store is incompatible with the one used to create the store"; } 

Muchas gracias por toda la ayuda que me puedas dar.

No puede encontrar la documentation sobre cómo crearlo correctamente porque, desde el punto de vista de Apple, no debería crearlo usted mismo en primer lugar. Si desea un model de datos central, debe usar los datos centrales para crear las tablas en lugar de crearlas usted mismo.

Si desea rellenar previamente la tabla con datos, puede hacerlo escribiendo código para hacerlo. Ese código puede ejecutarse dentro del código de inicio de su aplicación, o puede escribir una aplicación independiente para completar una database en un sistema de files, y luego importar ese file de database en su proyecto "real".

Sin embargo, si lo aborda, debe suponer que el uso de datos de núcleo con una tienda de persistencia SQlite significa que debería dejar que los datos centrales se encarguen de la creación de la tabla. Si desea escribir una aplicación basada en SQlite, puede hacerlo, pero Core Data no es la solución para usted.

Bien, entonces estoy de acuerdo con los comentarios anteriores. Use Core Data para build su database SQL. Si modifica la database directamente, todas las apuestas están desactivadas en términos de lo que Apple podría hacer con el formatting; Sin embargo, Apple debe garantizar la compatibilidad hacia atrás con Core Data, por lo que sus API DEBEN reenviar cualquier cosa que esté en cualquier formatting reciente válido.

Por lo tanto, para responder a su pregunta con información real (que es correcta a partir de diciembre de 2011 y iOS 4), aquí está una técnica que funcionará:

  1. Haga que los datos centrales creen la database para comenzar. Esta es su plantilla y contendrá los metadatos y las properties adecuados. Nunca debe usar DML en esto (sin tablas alter, etc.).

  2. La columna Z_ENT es la id de entidad, que se usa para rastrear la key primaria del object en la tabla ZPRIMARYKEY. Si examina la tabla de key principal, está rastreando la ID máxima ya utilizada en cada entidad (para la generación de Z_ID). También rastrea la inheritance, ya que los datos centrales utilizan una única tabla para todas las classs que tienen una relación de inheritance. Eg Manager es una subclass de Empleado. Habrá una sola tabla (zemployee), y la tabla de key primaria tendrá Z_SUPER configurada para apuntar a la fila real que rastrea los ID de la tabla. Si tiene subclasss, entonces Z_ENT indicará el tipo correcto para esa fila. Por ejemplo, si el Empleado es 1 y el Administrador es 2 en ZPRIMARYKEY, entonces habrá filas en ZEMPLOYEE con Z_ENT de 1 y 2.

  3. La columna Z_OPT es un recuento de las veces en que se ha escrito una fila (incluida la inserción … por lo que comienza en 1). Es casi seguro que se usa para la consistencia (por ejemplo, manejo optimizado de la concurrency de transactions). De todos modos, debería boostla cuando escribe en una fila.

Por supuesto, también debe mantener el campo MAX actualizado en la tabla de keys principales. ¡Asegúrate de hacer tu inserción y la actualización de la tabla PK juntas en las transactions para que no corrompa las cosas!

Y finalmente, por supuesto, no deberías estar haciendo esto en primer lugar 🙂

Necesitaba saber esto porque necesito un server de synchronization que no sea OSX para hacer frente a los files generados por los datos centrales … y, por lo tanto, no puedo usar la API de datos básicos directamente.

Actualización: septiembre de 2012

Una nota rápida sobre la inheritance. Si tiene relaciones FK de subclasss en su model de datos centrales, Core Data utiliza un model de inheritance de tabla única (búsquelo en los documentos de Hibernate para tener una mejor idea de lo que está sucediendo). La tabla única tendrá Z_ENT establecida en el tipo de class adecuado, y las foreign keys pueden necesitar más de una columna para manejar las alternativas presentes en las classs. Su mejor apuesta para asegurarse de que esto sea correcto es generar un pequeño set de datos en Objective-C con instancias de cada class y luego volcar los datos usando sqlite3 desde la línea de command. Será obvio qué tipo de datos usa qué columnas.

Así es como lo hago

  1. Cree su database en cualquier DBMS que desee (uso MySQL)
  2. Cree su entidad en Core Data, asegúrese de ejecutar su aplicación al less una vez para que las tablas se generen
  3. Exporte sus datos usando CSV
  4. Importarlos a Excel (sí, Excel: nunca pensé que Excel sería tan útil en esa tarea)
  5. Altere los nombres de columna en Excel para que coincidan con las versiones de Core Data (puede inspeccionar el file de la database para conocer los nombres de las columnas, utilizando un SQLMS DBMS. Utilizo un complemento de Firefox llamado SQLite Manager. El file de database reside en Library / Application Support / iPhone Simulator / versión / ID de la aplicación / Documents / file_name.sqlite) Pero aproximadamente, tiene Z_PK, Z_ENT y Z_OPT en cada tabla como las primeras columnas. Luego tiene sus propias columnas, mayúsculas y Z agregadas. Entonces col1 sería ZCOL1
  6. Agregue las columnas Z_ENT y Z_OPT. Establezca Z_OPT en 1, establezca Z_ENT en el valor especificado en la tabla Z_PRIMARYKEY. (Z_PK se agrega automáticamente durante la import, por lo que no es necesario hacerlo manualmente)
  7. Exportar CSV desde Excel
  8. Importe este file CSV en el file de la database (como se especifica en el paso 5) utilizando su SQLMS DBMS.

Espero eso ayude

Escribiría una aplicación de command-line de escritorio que utiliza datos centrales (y el mismo model que la aplicación de su teléfono) y rellena la tienda principal de datos persistentes, luego agrega los files a su aplicación iOS …

… o haga otro objective en su aplicación de iOS para hacerlo (puede ejecutar eso en el dispositivo si encuentra algún problema con el order de los bytes, pero no obtendrá una línea de command, simplemente inserte desde el código).