Cuando la API de la que dependes simplemente desaparece
La app de Dragon Ball nació hace tiempo como un proyecto colaborativo de prácticas de Git dentro de la comunidad de Discord de MoureDev. La hicimos entre varios para aprender a trabajar en equipo con control de versiones: ramas, pull requests, revisiones cruzadas. Con el paso del tiempo me di cuenta de que ese proyecto necesitaba una refactorización en condiciones, así que estas semanas me puse manos a la obra en serio.
El proyecto original se puede consultar en el repositorio Proyecto Dragon Ball Swift.
Por ahora, los cambios de esta revisión siguen únicamente en mi copia local. Cuando los publique, lo haré en una rama nueva para que se puedan consultar sin interferir con el trabajo anterior de mis compañeros.
El primer golpe fue descubrir que la app se había quedado sin datos. Uno de mis compañeros de equipo había montado una API propia en Vercel para el proyecto, y en algún momento ese servicio dejó de estar disponible. Sin avisar, sin deprecación, simplemente un día dejó de responder.
Esto me enseñó algo que ya sabía en la teoría pero no había sufrido en la práctica: cuando tu app depende de una API que no controlas, esa dependencia es un punto de fallo silencioso. No hay warning en Xcode que te diga “oye, esto se va a caer dentro de tres meses”.
La solución fue buscar una alternativa mantenida por la comunidad, dragonball-api.com, y migrar el consumo de datos hacia ahí. Pero la migración no fue un simple cambio de URL.
Los "pequeños" problemas que aparecieron al mirar de cerca
Al ponerme a revisar el código para hacer la migración, empezaron a salir cosas que llevaban tiempo escondidas:
- Errores tragados en silencio. Había bloques
catchvacíos y variables de error que se quedaban en blanco en vez de propagar el fallo real. Es decir: cuando algo fallaba, la app no se enteraba, y yo tampoco. Arreglar esto significó hacer que los errores reales llegaran hasta la interfaz en vez de desaparecer por el camino. - Llamadas en cascada donde no hacían falta. Para cargar los favoritos, el código lanzaba cinco llamadas de red seguidas, una por cada personaje, en vez de pedir todo de una vez. Funcionaba, pero era lento y frágil: si una fallaba, arrastraba a las demás. La solución fue centralizar la petición en una sola llamada.
- Paginación que no paginaba de verdad. La nueva API solo devuelve 10 resultados por página, pero el código pedía 58 de golpe asumiendo que llegarían todos. Aquí tocó implementar paginación real, trayendo los resultados en paralelo en vez de a lo bruto.
- Un modelo de datos que no encajaba con el nuevo. La API nueva no devuelve exactamente los mismos campos que la vieja (por ejemplo, no incluye el planeta del personaje). En vez de reescribir toda la parte visual que ya funcionaba, construí un adaptador que traduce el modelo nuevo al formato que las vistas ya esperaban. Fue más trabajo al principio, pero evitó tocar código que no tenía necesidad de tocar.
- Archivos fantasma. El descubrimiento más incómodo: unos cuantos archivos Swift existían en el disco, con código dentro, pero nunca habían sido añadidos al target de Xcode. Es decir, llevaban tiempo sin compilarse ni ejecutarse nunca, aunque parecía que formaban parte del proyecto. Tocó revisarlos uno a uno y darlos de alta donde correspondía.
Ninguno de estos problemas era, por separado, muy grave. Juntos, explicaban por qué la app se sentía inestable y por qué era tan difícil saber qué estaba pasando cuando algo fallaba.
Un archivo CSS corrupto que casi pasa desapercibido
El segundo frente fue mi portfolio, hecho con Ignite y publicado en GitHub Pages. Quería centrar todo el contenido y unificar el estilo visual. El resultado a simple vista parecía correcto, pero al revisar el histórico de commits encontré dos problemas de fondo:
- Uno de los commits había introducido una corrupción binaria al principio del archivo
main.css. Unos pocos bytes fuera de lugar, invisibles a simple vista, pero suficientes para que todas las variables CSS (colores, sombras, espaciados) dejaran de funcionar en producción. - En vez de editar las reglas de centrado ya existentes, se habían ido añadiendo bloques nuevos encima en distintos commits. El resultado era un CSS con reglas repetidas y, en algunos casos, contradictorias entre sí.
La solución no fue parchear encima (que es justo lo que había causado el problema), sino reescribir el archivo entero desde cero, limpio y consistente. Aquí el aprendizaje fue simple pero importante: cuando algo empieza a acumular parches sobre parches, muchas veces sale más barato pararse y reescribirlo bien que seguir apilando arreglos.
Lo que me llevo de todo esto
- Los errores más peligrosos no son los que rompen la app a la vista, sino los que se quedan callados (un
catchvacío, una corrupción de un archivo que “funciona a medias”). - Depender de una API externa sin plan B es aceptar un riesgo que tarde o temprano se cobra su precio.
- Revisar código antiguo con calma, archivo por archivo, saca a la luz cosas que nunca habrías encontrado añadiendo funcionalidades nuevas.
- A veces la solución elegante no es la más rápida de escribir, sino la que evita tener que tocar diez sitios más adelante (como el adaptador de modelos, en vez de reescribir toda la UI).
Todavía queda trabajo por delante, sobre todo decidir cómo reorganizar la parte de la wiki por sagas, ya que la nueva API no separa los personajes de esa forma. Pero el proyecto ya compila entero, ya no traga errores en silencio, y el portfolio por fin se ve como quería que se viera.
Si estás en medio de un refactor parecido: revisa siempre el git log con calma antes de asumir que un archivo “está bien porque compila”. A veces no cuenta toda la historia.