Guardo una última marca de tiempo modificada en la base de datos tanto en los registros de datos centrales en el teléfono como en las tablas mysql en el servidor.
El teléfono busca todo lo que ha cambiado desde la última sincronización y lo envía al servidor junto con una marca de tiempo de la última sincronización, y el servidor responde con todo lo que ha cambiado desde la marca de tiempo de sincronización proporcionada.
El rendimiento es un problema cuando muchos registros han cambiado. Hago la sincronización en una NSOpeartion de fondo que tiene su propio contexto de objeto administrado. Cuando el subproceso de fondo ha terminado de realizar cambios en su contexto de objeto administrado, hay una API para fusionar todos los cambios en el contexto de objeto administrado del subproceso principal, que se puede configurar para simplemente eliminar todos los cambios si hay algún conflicto causado por el usuario cambia los datos mientras se realiza la sincronización. En ese caso, solo espero unos segundos y luego intento hacer una sincronización nuevamente.
En hardware más antiguo, incluso después de muchas optimizaciones, era necesario cancelar la sincronización por completo si el usuario comienza a hacer cosas en la aplicación. Simplemente estaba usando demasiados recursos del sistema. Creo que los dispositivos iOS más modernos probablemente sean lo suficientemente rápidos como para que ya no necesites hacer eso.
(por cierto, cuando dije "muchos registros han cambiado" me refería a unas 30 000 filas actualizadas o insertadas en el teléfono)