# El camino para crear apps Apple no cambia porque uses IA

Puedes escribir cada línea a mano, apoyarte en un asistente o pedirle a un agente que construya la aplicación. Incluso puedes hacer *vibe coding* y aceptar lo que genera sin revisar el código. Cambia tu intervención. Lo que necesita la app para funcionar bien sigue siendo lo mismo.

Los datos necesitan una estructura. Una operación puede fallar. La interfaz debe responder mientras llega información. Y alguien tendrá que poder utilizar el resultado sin adivinar cómo funciona. Ninguna de esas necesidades desaparece porque el código lo haya escrito una IA.

Ese es el sentido de este roadmap: mostrar el camino completo, desde los fundamentos hasta la App Store. **Podemos delegar la ejecución de los pasos, pero no saltarnos lo que resuelven.** Si no lo hacemos nosotros, tendrá que hacerlo la herramienta que utilicemos. Y si nadie lo hace, lo que queda es un problema pendiente, no un atajo.

Son 21 pasos conectados. No significa estudiar toda la teoría antes de construir nada ni convertirlos en compartimentos estancos. Se aprende haciendo, se vuelve atrás y se corrige. Pero el recorrido sigue siendo este.

![Comenzamos con lo más básico. Sin pilares no hay resultados.](https://image.service.eu.axinom.net/transform/72a20w8irkd812lj5hqycl0ft-3dl5y1dj0seejmhh8wynzscv2/WPga8SUkoUqCiEvnHXYP8Z.png)

## 1. Fundamentos de la programación

Un programa recibe información, toma decisiones y produce resultados. Antes de preocuparnos por Swift necesitamos entender esa mecánica: guardar un valor, comparar dos cosas, repetir una operación o dividir un problema en otros más pequeños. Es lo que permite pasar de «quiero una app que haga esto» a explicar qué tiene que ocurrir. Sin esa base podemos pedir un resultado, pero nos faltará criterio para reconocer si realmente lo hemos conseguido.

## 2. Algoritmia

Decir «ordena esta lista» expresa una intención. Decidir cómo ordenarla es resolver el problema. La algoritmia nos enseña a construir esos procedimientos y a valorar cuánto trabajo requieren. No hace falta convertir cada pantalla en un ejercicio matemático, pero sí entender por qué buscar un dato recorriendo miles de elementos una y otra vez puede ser una mala decisión.

## 3. Fundamentos del lenguaje

Ahora necesitamos expresar esas ideas en Swift. Declaraciones, funciones, parámetros, ámbitos y opcionales forman parte de su vocabulario. Un opcional, por ejemplo, permite representar que un dato puede no existir, en lugar de fingir que siempre estará disponible. Aprender el lenguaje no consiste en memorizar sintaxis: consiste en poder describir el problema con precisión y entender qué nos está diciendo el compilador cuando algo no encaja.

## 4. Tipos de datos

Un precio, una fecha y el nombre de una persona no son información intercambiable. Los tipos nos permiten representar esas diferencias y limitar las operaciones que tienen sentido. Después llegan las colecciones, las estructuras, las enumeraciones o las clases para organizar modelos más completos. Modelar bien evita tener que corregir después, con comprobaciones dispersas, errores que podríamos haber impedido desde el principio. Los datos no se arreglan solo porque una pantalla los muestre bien.

![Seguimos avanzando y terminar de entender cómo se monta la app es esencial](https://image.service.eu.axinom.net/transform/72a20w8irkd812lj5hqycl0ft-3dl5y1dj0seejmhh8wynzscv2/WCfrL2VFEmUtHiNREwhsyS.png)

## 5. Estructuras del lenguaje

Swift permite crear nuestros propios tipos: `struct` para modelar valores, `class` para objetos con identidad y semántica de referencia, `enum` para expresar alternativas y `actor` para aislar estado mutable. Así, una reserva deja de ser un puñado de variables sueltas y se convierte en un concepto con datos y comportamiento. Eso es abstraer: representar lo importante del problema y ocultar detalles que otras partes no necesitan conocer. Elegir bien estas estructuras permite razonar sobre cada pieza sin tener que entender toda la aplicación a la vez.

## 6. Programación funcional

En Swift, una función también es un valor con un tipo: podemos guardarla, pasarla como argumento o devolverla desde otra función. Los closures permiten expresar ese comportamiento y capturar su contexto. El cambio de mentalidad está en dejar de pasar solo datos y empezar a pasar también qué hacer con ellos. Una validación puede recibir la regla que debe aplicar, en lugar de tenerla fijada dentro. Así separamos el mecanismo del comportamiento y podemos combinarlos sin duplicar la solución.

## 7. Herramientas del lenguaje para apps

Los errores, los protocolos y los genéricos empiezan a cobrar sentido cuando dejamos atrás los ejemplos aislados. Necesitamos comunicar que una operación ha fallado, definir qué debe ofrecer un componente o reutilizar una solución conservando la seguridad de tipos. Estas herramientas permiten que las piezas colaboren sin depender de todos sus detalles internos. Por eso importan: ayudan a construir una aplicación que pueda cambiar, no solo un ejemplo que consiga ejecutarse.

## 8. Diseño de apps y HIG

Una pantalla puede ser muy vistosa y resultar incómoda de utilizar. Las Human Interface Guidelines de Apple ayudan a entender cómo se organiza una experiencia coherente con la plataforma: navegación, jerarquía visual, controles y respuesta a las acciones. No son un catálogo para copiar pantallas. Nos dan criterios para que la persona reconozca qué puede hacer y qué está ocurriendo, sin tener que aprender nuestras ocurrencias antes de empezar.

![La arquitectura es esencial si queremos que nuestra app crezca y que mantenerla no sea un infierno. Qué decir de su uso, datos y la accesibilidad.](https://image.service.eu.axinom.net/transform/72a20w8irkd812lj5hqycl0ft-3dl5y1dj0seejmhh8wynzscv2/FKFbyCBtcRaazmi4ozRvJ4.png)

## 9. Arquitecturas: MVVM

Cuando la interfaz, el estado y las operaciones terminan mezclados, cualquier cambio puede afectar a demasiadas cosas. Una arquitectura organiza esas responsabilidades. MVVM, que separa modelo, vista y modelo de vista, es una forma de abordar el problema. Lo importante no es acumular carpetas ni imponer una sigla a cualquier proyecto: es poder localizar una decisión, cambiarla y comprobarla sin desmontar media aplicación. También cuando la estructura la ha propuesto una IA. Inyección de dependencias, reutilización, separar cada parte en una unidad independiente. Esto nos permite escalar la app y que crezca sin miedo a convertirse en un monstruo indomable.

## 10. Flujos de negocio de los datos

Antes de decidir cómo mostramos una operación hay que saber qué significa. Confirmar una reserva, por ejemplo, exige comprobar disponibilidad, aplicar unas reglas y conservar un resultado coherente. Esas son decisiones de negocio, aunque no haya dinero de por medio. Definen de dónde vienen los datos, qué condiciones deben cumplir y cómo cambian. Si esas reglas están mal, una interfaz impecable solo servirá para presentar mejor una operación incorrecta.

## 11. Flujos de experiencia de usuario

Ahora toca convertir esa operación en un recorrido que una persona pueda completar. ¿Cómo empieza? ¿Qué ve mientras espera? ¿Puede cancelar? ¿Cómo se recupera de un error? El flujo de negocio explica qué debe suceder; el de experiencia de usuario, cómo lo vive quien utiliza la app. Una reserva puede haberse guardado correctamente y, aun así, provocar un segundo intento si nunca mostramos que la primera se confirmó.

## 12. Accesibilidad

El tamaño del texto, el contraste, el orden de lectura o las etiquetas de VoiceOver determinan quién puede utilizar una aplicación. No son detalles que añadimos al terminar para cumplir un trámite. Forman parte del diseño de los controles y de la información. Si un error solo se comunica cambiando algo de color, ya hemos dejado fuera a parte de los usuarios. Resolverlo desde el principio es construir bien, no hacer una versión especial después.

![Concurrencia, red, arquitecturas, nuestras propias librerías y componentes... sin esto, no hay app que valga](https://image.service.eu.axinom.net/transform/72a20w8irkd812lj5hqycl0ft-3dl5y1dj0seejmhh8wynzscv2/Q4QscpbGogCwwtUeQwrdXJ.png)

## 13. Concurrencia

Necesitamos entender cómo se ejecuta nuestra app por dentro: qué trabajo puede avanzar de forma concurrente, cómo se separa y qué estado pertenece a cada dominio de aislamiento. Una *data race* aparece cuando hay accesos concurrentes sin coordinación a la misma memoria y al menos uno modifica su contenido. La concurrencia estricta de Swift comprueba reglas de aislamiento y transferencia de datos para detectar accesos inseguros antes de ejecutar. No se trata solo de hacer varias cosas a la vez, sino de impedir que interfieran entre sí y provoquen errores difíciles de reproducir.

## 14. Uso de red

Las APIs asíncronas de `URLSession`, utilizadas con `async/await`, permiten esperar una respuesta sin bloquear el hilo que ejecuta la tarea. Pero una petición debe encajar en la configuración de concurrencia de nuestra app. Hay que decidir dónde se procesa la respuesta, evitar cálculos costosos en el actor principal y actualizar allí el estado de la interfaz. También gestionar errores y cancelaciones respetando el aislamiento. No basta con añadir `await`: necesitamos organizar todo ese recorrido para que descargar y transformar datos no congele la aplicación.

## 15. Arquitectura escalable concurrente

Coordinar unas tareas no es lo mismo que organizar toda una aplicación que comparte datos entre ellas. Aquí entran el aislamiento, los actores y la gestión del ciclo de vida del trabajo. Imaginemos dos búsquedas: la primera termina después y sobrescribe los resultados de la segunda. No basta con evitar accesos simultáneos; también debemos decidir qué resultado sigue siendo válido. Escalar consiste en conservar ese control al crecer, no en añadir complejidad por anticipado.

## 16. Librerías

Crear nuestras propias librerías permite separar funcionalidades en módulos con responsabilidades claras y una interfaz pública definida. Por ejemplo, podemos encapsular el acceso a la red en un paquete Swift y utilizarlo sin exponer sus detalles internos al resto de la app. Así resulta más práctico probar, mantener y reutilizar nuestro código sin copiarlo ni mezclarlo todo en el mismo sitio. Aquí no hablamos de acumular dependencias ajenas: las librerías de terceros solo deberían entrar cuando sean absolutamente necesarias y exista una razón concreta que lo justifique.

![Test, bases de datos, la seguridad de nuestros datos, despliegue... sin esto, estamos creando una caja de bombas](https://image.service.eu.axinom.net/transform/72a20w8irkd812lj5hqycl0ft-3dl5y1dj0seejmhh8wynzscv2/25Cx73aDXwTh4XsuWGfTD6.png)

## 17. Testing

Que compile significa que ha superado las comprobaciones del compilador. No demuestra que haga lo correcto. Las pruebas permiten verificar reglas, integraciones y recorridos, y repetir esas comprobaciones cuando cambiamos algo. Esto incluye tests de UI que recorren pantallas y ejecutan acciones, y pruebas de accesibilidad para comprobar qué anuncia VoiceOver, en qué orden y cómo responde al interactuar con los controles. Una interfaz puede funcionar al tocarla y seguir siendo incomprensible para quien la escucha. Hay que probar también datos vacíos, errores y situaciones menos cómodas. Si una IA genera los tests, necesitamos comprobar que las expectativas representan el comportamiento que buscamos, no que el código y sus pruebas comparten la misma equivocación.

## 18. Bases de datos: SwiftData

El estado que vive en memoria desaparece cuando termina la aplicación. La información que debe conservarse necesita persistencia. SwiftData ofrece herramientas para trabajar con modelos, relaciones y consultas, pero seguimos teniendo que decidir qué guardamos y cómo evoluciona su estructura. Una actualización no debería hacer perder los datos de quien ya usa la app. Por eso las migraciones forman parte del problema, no son una sorpresa que dejamos para el día de publicar.

## 19. Seguridad en comunicaciones y datos

¿Qué datos recogemos? ¿Quién puede consultarlos? ¿Dónde quedan guardados? La seguridad empieza al responder esas preguntas, no al añadir una capa al final. Comunicaciones cifradas, credenciales almacenadas adecuadamente —por ejemplo, tokens en el llavero del sistema— y permisos mínimos son parte del trabajo. También lo es no incrustar secretos en una app que vamos a distribuir. Un dato sigue necesitando protección aunque ninguna persona haya leído el código que lo maneja.

## 20. Entornos de despliegue

La app del simulador todavía no es la app que llegará al usuario. Necesitamos controlar configuraciones de desarrollo, pruebas y producción para no mezclar servicios ni datos. También resolver la firma, la distribución y las comprobaciones en dispositivos reales. TestFlight ayuda a validar versiones antes de publicarlas. Y sí, hay que comprobar la configuración final: haber probado contra un servidor de desarrollo no demuestra que la versión de producción funcione.

![El App Store es todo un reto en sí mismo. No lo menosprecies.](https://image.service.eu.axinom.net/transform/72a20w8irkd812lj5hqycl0ft-3dl5y1dj0seejmhh8wynzscv2/Rhm3are2GVodxr6q5fgJxM.png)

## 21. Metadatos y App Store

El recorrido termina presentando el producto de forma fiel: nombre, descripción, capturas, información de privacidad y datos necesarios para su revisión. Esa ficha también forma parte de la experiencia. Prometer algo que la app no hace o describir mal cómo utiliza los datos no se arregla con un buen binario. Publicar significa entregar una aplicación y explicar con honestidad qué recibe quien decide descargarla. Y hay que crear una landing web, soporte, información de privacidad... el trabajo no acaba solo con la app. Ni que decir tiene lo necesario en modelos de negocio, información a Apple, notas de revisión... mucho trabajo aquí para acabar.

## El camino sigue ahí

No hace falta dominar estos 21 puntos antes de empezar. Tampoco todas las apps necesitan la misma profundidad en cada uno. Pero usar IA no convierte los fundamentos en opcionales y delegar una implementación no elimina las decisiones que contiene. Algunas etapas se trabajan a la vez; otras nos obligan a volver sobre lo anterior. Eso también forma parte de desarrollar.

Este es el camino, tanto si escribimos el código como si dirigimos a una herramienta que lo escribe por nosotros. No hay un camino alternativo que convierta en innecesarios los datos, la experiencia, la calidad o la seguridad. Hay distintas formas de hacer ese trabajo.

**La IA puede ahorrarnos escribir mucho código. No puede hacer que deje de importar lo que ese código hace.**
