Core Data Cloud Sync: necesito ayuda con la lógica

Estoy en medio de una lluvia de ideas sobre una solución de sincronización en la nube para una aplicación Core Data que estoy desarrollando actualmente. Estoy planeando abrir el código fuente para esto una vez que esté listo, para que cualquiera lo use con sus aplicaciones de Core Data, por lo que se agradece la opinión de la comunidad sobre cómo debería funcionar este sistema :-) Esto es lo que estoy pensando:

Lado del servidor

Proveedor de almacenamiento

Al igual que con todos los sistemas de sincronización en la nube, el almacenamiento es una pieza importante del rompecabezas. Hay muchas formas de manejar esto. Podría configurar mi propio servidor para el almacenamiento, o utilizar un servicio como Amazon S3, pero debido a que estoy comenzando con $ 0 de capital, en este momento, una solución de almacenamiento de pago no es una opción viable. Después de pensarlo un poco, decidí conformarme conDropbox (un proveedor de almacenamiento y aplicación de sincronización en la nube bien establecido). Las ventajas de usar Dropbox son:

Es gratis (por una cantidad limitada de espacio)Además de ser un servicio de almacenamiento, también maneja la sincronización en la nubeRecientemente lanzaron un Objective-C SDK que hace que sea mucho más fácil interactuar con él en aplicaciones para Mac y iPhone

En caso de que decida cambiarme a un proveedor de almacenamiento diferente en el futuro, tengo la intención de agregar "servicios" a este marco de sincronización en la nube, básicamente permitiendo que cualquiera pueda crear una clase de servicio para interactuar con su proveedor de almacenamiento elegido, que luego simplemente puede ser enchufado en el marco.

Estructura de almacenamiento

Esta es una parte realmente difícil de entender, por lo que necesito tanta información como pueda aquí. He estado pensando en una estructura como esta:

CloudSyncFramework
======> [app name]
==========> devices
=============> (device id)
================> deviceinfo
================> changeset
==========> entities
=============> (entity name)
================> (object id)

Una explicación rápida de esta estructura:

La carpeta maestra "CloudSyncFramework" (nombre indeciso) contendrá carpetas separadas para cada aplicación que use el marcoCada carpeta de la aplicación contiene undispositivos carpeta y unentidades carpetalosdispositivos La carpeta contendrá una carpeta para cada dispositivo que esté registrado con la cuenta. La carpeta del dispositivo se nombrará de acuerdo con la ID del dispositivo, obtenida usando algo como[[UIDevice currentDevice] uniqueIdentifier] (en iOS) o un número de serie (en Mac OS).Cada carpeta del dispositivo contiene dos archivos:información del dispositivo yconjunto de cambios. información del dispositivo contiene información sobre el dispositivo (por ejemplo, versión del sistema operativo, última fecha de sincronización, modelo, etc.) y elconjunto de cambios El archivo contiene información sobre los objetos que han cambiado desde la última sincronización del dispositivo. Ambos archivos serán simples NSDictionaries archivados en archivos usandoNSKeyedArchiver.Cada entidad de Core Data tiene una subcarpeta debajo deentidades carpetaDebajo de cada carpeta de entidad, cada objeto que pertenece a esa entidad tendrá un archivo separado. Este archivo contendrá un diccionario JSON con los pares clave-valor.

Sincronización Simultánea

Esta es una de las áreas donde estoy casi completamente desorientado.¿Cómo manejaría 2 dispositivos conectados y sincronizados con la nube al mismo tiempo? Parece que hay un alto riesgo de que las cosas no estén sincronizadas aquí, o incluso la corrupción de datos.

Manejo de migraciones

Una vez más, otra área despistada aquí.¿Cómo manejaría las migraciones del modelo de objetos gestionados de Core Data? Lo más fácil de hacer aquí parece ser simplemente limpiar el almacén de datos de la nube y cargar una nueva copia de los datos de un dispositivo que se ha sometido al proceso de migración, pero esto parece algo arriesgado, y puede haber una mejor manera.

Lado del cliente

Convirtiendo NSManagedObjects en JSON

La conversión de atributos a JSON no es una tarea muy difícil (hay mucho código flotando en la web). Las relaciones son el problema clave aquí. Enesta stackoverflow post, Marcus Zarra publica código en el que los objetos de relación se agregan al diccionario JSON. Sin embargo, menciona que esto puede causar un bucle infinito dependiendo de la estructura del modelo, y no estoy seguro de si esto funcionaría con mi método, porque almaceno cada objeto como un archivo individual.

He estado tratando de encontrar una manera de obtener una ID como una cadena para unNSManagedObject. Entonces podría guardar relaciones en JSON como una matriz de ID. Lo más cercano que encontré fue[[managedObject objectID] URIRepresentation], pero esto no es realmente una ID para un objeto, es más una ubicación para el objeto en el almacén persistente, y no sé si es lo suficientemente concreto como para usarlo como referencia para un objeto.

Supongo que podría generar una cadena UUID para cada objeto y guardarla como un atributo, pero estoy abierto a sugerencias.

Sincronizando cambios a la nube

La primera (y aún la mejor) solución que surgió en mi cabeza para esto fue escuchar elNSManagedObjectContextObjectsDidChangeNotification para obtener una lista de objetos modificados, luego actualice / elimine / inserte esos objetos en el almacén de datos en la nube. Después de guardar los cambios, necesitaría actualizar elconjunto de cambios archivo para cada otro dispositivo registrado para reflejar los objetos recién cambiados.

Un problema que surge aquí es,¿Cómo manejaría una sincronización fallida o interrumpida?. Una idea que tengo es empujar primero los cambios a un directorio temporal en la nube, luego, una vez que se haya confirmado que es exitoso, fusionarlo con los datos maestros en la nube para que una interrupción en el medio de la sincronización no se corrompa datos. Luego, guardaría los registros de los objetos que deben actualizarse en la nube en un archivo plist o algo así, para que se envíen durante la próxima vez que la aplicación se conecte a Internet.

Recuperando objetos modificados

Esto es bastante simple, el dispositivo descarga suconjunto de cambios archivo, determina qué objetos deben actualizarse / insertarse / eliminarse, luego actúa en consecuencia.

Y eso resume mis pensamientos sobre la lógica que utilizará este sistema :-) Cualquier idea, sugerencia, respuesta a problemas, etc. esmuy apreciado.

ACTUALIZAR

Después de pensar mucho y leer las sugerencias de TechZens, se me ocurrieron algunas modificaciones a mi concepto.

El cambio más grande que he pensado es hacer que cada dispositivo tenga unseparar almacén de datos en la nube. Básicamente, cada vez que el contexto del objeto gestionadoahorra (gracias TechZen), cargará los cambios en el almacén de datos de ese dispositivo. Después de que esos cambios se actualicen, creará un archivo "conjunto de cambios" con detalles de cambio y lo guardará en las carpetas de conjunto de cambios de los OTROS dispositivos que están utilizando la aplicación. Cuando los otros dispositivos se conectan para sincronizar, irán a través de la carpeta del conjunto de cambios y aplicarán cada conjunto de cambios al almacén de datos local, luego actualizarán sus respectivos almacenes de datos en la nube también.

Ahora, si un nuevo dispositivo está registrado con la cuenta, encontrará elel más nuevo copia de los datos de todos los dispositivos y descárguelos para usarlos como almacenamiento local.Esto resuelve el problema de la sincronización simultánea y reduce las posibilidades de corrupción de datos porque no hay un almacén de datos "central", cada dispositivo toca solo sus datos y solo actualiza los cambios en lugar de que cada dispositivo acceda y modifique los mismos datos al mismo tiempo.

Hay algunas situaciones de conflicto obvias con las que lidiar, principalmente en relación con la eliminación de objetos. Si se está descargando un conjunto de cambios que indica a la aplicación que elimine un objeto que se está editando actualmente, etc., debe haber formas de lidiar con esto.

Respuestas a la pregunta(4)

Su respuesta a la pregunta