Core Data Sync: seguimiento de objects eliminados

Estoy configurando un service de synchronization básica para una aplicación de iPad que estoy desarrollando. El objective es tener datos consistentes a lo largo de varias instancias de la aplicación iPad, además de tener una versión de solo lectura de los datos en la web, por lo tanto, lanzar una solución personalizada.

El flujo actual es el siguiente:

  • Cada entidad tiene un campo 'creado', 'modificado' y 'UUID' que son actualizados automáticamente por Core Data
  • En synchronization, cada entidad con una date creada o modificada después de la última date de synchronization se serializa en JSON y se envía al server
  • El server persiste en cualquier cambio a una database MySQL usando los UUID generados por el cliente como PKs (si hay un conflicto, solo usa la entidad modificada más reciente como la versión 'verdadera', nada de lo que se desee) y devuelve las entidades actualizadas a la cliente
  • El cliente vuelve a combinar estos cambios en su database de base

Todo parece funcionar bien. Mi problema es cómo rastrear los objects eliminados con este método. Supongo que puedo agregar una bandera 'eliminada' a cada entidad y configurarla cuando un cliente borre algo, luego puedo enviar ese cambio al server con el rest de los datos de synchronization. Una vez que se completa la synchronization, el cliente puede eliminar estas entidades. Mis preguntas son:

  • ¿Puedo anular los methods de eliminación de Core Data para configurar automáticamente este indicador?
  • ¿Esto requerirá mantener todas las entidades eliminadas indefinidamente en el server? No tendremos forma de saber cuándo cada cliente ha sincronizado y eliminado realmente cada entidad (actualmente no estoy rastreando las instancias de los clientes)
  • ¿Hay una mejor manera de hacer esto?

¿Qué tal si mantienes una tabla de historial delta con UUID y un campo creado / actualizado / eliminado, tal vez con un número de revisión para cada actualización? Por lo tanto, mantiene una pequeña list de verificación de cambios desde su última synchronization exitosa.

De esta manera, si elimina un object, puede agregar una input en la tabla de historial delta con el UUID eliminado y marcarlo como eliminado. Lo mismo con los objects creados y actualizados, solo necesita verificar la tabla delta para ver qué elementos necesita el server para eliminar, actualizar, crear, etc. Incluso puede almacenar cada revisión en el server para admitir volver a una versión anterior en El futuro si lo deseas.

Creo que un número de revisión es mejor que confiar en el reloj del cliente que podría cambiarse manualmente.

Puede utilizar los objects insertados, los objects actualizados, los methods eliminados de NSManagedObjectContext para crear los objects delta antes de cada procedimiento de salvar 🙂

Mis 2 centavos

Con respecto a su segunda pregunta: puede diseñar esto para que el server no tenga que mantener loggings eliminados, si así lo desea. Deje saber a cada aplicación si un dato determinado (basado en su UUID) se almacena en el server (por ejemplo, agregue una propiedad existsOnServer o similar). Esto comienza en falso cuando se crea un elemento nuevo en la aplicación, pero se establece en verdadero una vez que se ha sincronizado con el server por primera vez. De esta manera, si la aplicación intenta sincronizarse más tarde, pero el UUID no se encuentra, puede diferenciar los dos casos: Si existsOnServer es falso, entonces este elemento se acaba de crear y se debe sincronizar con el server, pero si es cierto entonces puede entenderse que ya estaba en el corte antes, pero ahora se ha eliminado, por lo que también puede eliminarlo en la aplicación.

Probablemente podría argumentar en contra de este enfoque, ya que me parece más propenso a errores (me imagino que un error de connection o de database se interpretó incorrectamente como una eliminación) y mantener loggings alnetworkingedor de su server normalmente no sería un gran problema, pero es posible. El "delta-approach" sugerido por dzeikei podría usarse al mismo time, por lo que una actualización de un logging que no existe en el server significa que se eliminó, mientras que una inserción no.

Si debe o no mantener los objects borrados en el server o no depende totalmente de sus necesidades. Necesitará una bandera eliminada localmente para marcar como eliminada para la synchronization, tal vez también en el server, dependiendo de su deseo de retroceder.

Me he ocupado de este problema algunas maneras antes. Aquí hay una posibilidad:

Cuando un cliente borra algo, simplemente marque que se elimine localmente y elimine del server durante la synchronization (en ese momento puede purgarse de los datos básicos). Cuando otros clientes solicitan acceder a esos datos, envíe un HTTP 404 porque ya no tiene el object. En ese punto, el cliente puede eliminar la entidad localmente. Ahora bien, si un cliente solicita una list de cosas y este object ha sido eliminado, simplemente faltará a la list de cosas que vuelve para que pueda detectar eso y eliminarlo. Lo hago en un cliente creando una matriz de ID de object cuando obtengo una respuesta del server y borrando cualquier object local que no tenga esas ID.

Tenemos un campo eliminado en el server, pero solo para tener la capacidad de retroceder en caso de que algo se elimine por crash.

Por supuesto, puede devolver los objects borrados al cliente para que sepan eliminarlos, pero si no desea conservar una copy en el server, debe asumir que todos los clientes se actualizarán dentro de un período de time. Entonces podrías recolectar basura después de que el marco de time haya caducado.

Sin embargo, realmente no me gusta esa solución. Si sus datos son demasiado pesados ​​para solicitar todos los objects para una synchronization completa, puede usar su estrategia de combinación actual para crear y actualizar, y luego ejecutar una llamada por separado para verificar los elementos eliminados. Esa llamada podría simplemente solicitar todas las identificaciones que el cliente debería tener en el dispositivo. Podría eliminar los que no existen. O podría enviar todas las identificaciones en el cliente y get una list de ID para eliminar.

Creo que debe proporcionar más detalles sobre la naturaleza de los datos si desea una sugerencia más obstinada.

Puede consultar la Sincronización de datos entre plataforms de Dan Grover si no lo ha hecho. Es un artículo muy bien escrito sobre synchronization e iOS.

Acerca de sus preguntas:

  1. Puede evitar eliminar un file en Core Data y establecer un 'flag eliminado': simplemente actualice el file en lugar de eliminarlo. Podrías hacer tu propio método de "eliminación" que llamaría y actualizaría la bandera en el logging.

  2. Mantenga siempre un last_sync y un last_updated para cada logging en el server y en cada cliente. De esta forma siempre sabrás cuándo alguien cambió algo en cualquier lugar y si ese cambio se sincronizó o no con la 'database de verdad'.

  3. Hacer un seguimiento de los files borrados es algo difícil de hacer, supongo que la mejor manera de hacerlo es hacer un seguimiento del historial de sincronizaciones para cada tabla, pero es una tarea difícil. La forma más fácil, usar este tipo de configuration de "database de verdad" es marcar los files, así que sí, debe mantener los datos tanto en el server como en el cliente.

durante la synchronization de datos entre la tabla de remolque algunos loggings o eliminados cuando las filas de la tabla son iguales. y cuando las filas son diferentes, sincronizadas correctamente, utilicé este Código, haga clic aquí en la image

introduzca la descripción de la imagen aquí