El podcast de Sergio
El podcast de Sergio
Ep. 27 25 octubre 2026 · 4m 25s

La pesadilla de CloudKit

The CloudKit nightmare

El domingo quise probar si LiftCoach sincroniza por CloudKit. El iPad no tenía el diario. iCloud llevaba parado desde el 18 de junio: un registro malo tiraba el paquete entero. Primero parecía un borrado y al final era el esquema. Post completo: https://sergiocomeron.com/blog/posts/el-diario-se-quedo-en-junio/

On Sunday I tried to see if LiftCoach syncs through CloudKit. The iPad had no diary. iCloud had been stuck since 18 June: one bad record rejected the whole batch. It looked like a delete, and it was the schema. Full post: https://sergiocomeron.com/blog/en/posts/el-diario-se-quedo-en-junio/

0:00--:--

Lo escribe Sergio. Lo lee una voz generada · Written by Sergio. Read by a generated voice · Colophon

TranscripciónTranscript · del guión del episodio· from the episode script

La semana, en el trabajo, ya da para llenarla. Un aviso de PHP. Alguien llamando a la puerta del servidor, a ver si cede. Parches, Moodle, y esa sensación de que cierras una brecha y asoma la siguiente. Con eso, un viernes, bastaría.

El fin de semana, no. El fin de semana sigo. Y este domingo me he puesto a probar si mi app de gimnasio se sincroniza sola entre el teléfono y el iPad.

El título de hoy: la pesadilla de CloudKit.

La app es LiftCoach. La estoy haciendo yo, para el iPhone, el iPad y el reloj. Todavía no está en la tienda. La uso de verdad, mientras la escribo. El diario es el mío. Los fallos, también. Y esto es el podcast.

Quería ver el mismo entreno en el iPad. Abrí la app y no había nutrición. Tampoco historial. En el teléfono estaba todo. Lo normal es pensar que el iPad aún no ha terminado de bajar. No estaba bajando. No había nada que bajar.

Para mirarlo de verdad lo enchufé con el cable. Lo desbloqueé. Y le dije al ordenador que sí, que de ese aparato se fiara. Hace falta tener puesto el modo de desarrollador. En el iPad ya lo tenía. En el teléfono tuve que encenderlo antes de poder hacer lo mismo.

Y aun así, el primer cajón estaba vacío. La base de datos no vive en la carpeta de la app. Vive en un grupo que comparten la app y el reloj. Y no basta el archivo grande. Al lado hay dos compañeros, los que apuntan lo que aún no se ha asentado. Si te dejas esos, la foto miente.

Con la copia en el Mac, conté. Comidas. Entrenos. Agua. En el iPad, un puñado de filas de primavera. En el teléfono, meses. Luego miré el cuaderno de las subidas. Hasta el dieciocho de junio entraban. A partir de ahí, una detrás de otra. Un segundo. Error. Y cero registros guardados. iCloud se había quedado en junio. Lo demás vivía solo en el teléfono.

Los logs del propio iPad no salían. Pedían ser administrador, y no era plan de domingo. El otro lado lo leí en el panel de CloudKit, en producción, a la misma hora. El servidor decía que la petición era mala. Y no decía qué registro. En esa base el contenido va cifrado. El panel enseña el sobre, no el nombre.

El primer intento que pude leer no era un guardado. Era un borrado. En la cola había filas que en el teléfono ya no existían, y que casi nunca habían llegado a la nube. El servidor las rechazaba. Y como el paquete es de todo o nada, detrás no subía ni una comida.

Rechazarlas no había borrado nada allí. El diario seguía entero. Con la app cerrada, y una copia aparte por si acaso, quité esas marcas de borrado. No toqué las comidas. Ni los entrenos.

Abrí otra vez. Ahora sí era un guardado. Y también lo rechazó. El mismo segundo. El mismo error. Para no aburrirnos.

El modelo había crecido desde junio. Un historial de recetas. Una comida marcada como antes del entreno, durante, o después. El código de barras de un alimento mío. Una serie con su descanso y su hora. En las pruebas, iCloud aprende un campo cuando guardas un registro que lo trae. En la versión que usa la app de verdad, no. Esa solo cambia si despliegas el esquema. Y desplegar copia los tipos y los campos. No copia las comidas. Tampoco las borra.

El primer despliegue no bastó. Las pruebas iban con los huecos vacíos, y un hueco vacío no se crea. El paquete de verdad sí los llevaba. Con uno que el servidor no conoce, rebota todo el domingo.

Volví a guardar pruebas, esta vez rellenas, en un almacén aparte. No en el diario. Desplegué. Abrí el teléfono. En un minuto la cola se vació. El número de comidas no se movió. Lo que estaba en el iPhone pasó a estar en iCloud.

El iPad era otra historia. Cuando sincronizó, solo podía recibir junio. Un entreno llegaba antes que sus series, y la app lo tomaba por abandonado. Esos borrados tampoco salieron. Pero la copia local se creyó al día. Para ella, junio era todo el mundo. Poner la versión nueva encima no servía. Borré la app solo ahí, y volví a instalar la misma que ya tenía el teléfono. Bajó el diario entero. Aparecieron la nutrición, y el sábado, con las series hechas. En el teléfono no quité nada. Hasta ese minuto, era la única copia completa.

La semana ya había tenido sus avisos y sus puertas. El domingo, para no aburrirnos, me lié con esto. Los comandos, que aquí no caben, están en el blog.

Esto ha sido el podcast de Sergio por hoy. Nos escuchamos en el próximo.