Crear el proyecto Pokédex
Al terminar: Instalar el plugin de Kotlin Multiplatform, generar el proyecto en ~/Pokedex-KMP y llevarlo al stack exacto que usa la guía.
Hasta aquí has instalado herramientas y has construido Marcador. A partir de aquí empieza la Pokédex. En esta lección generas el proyecto: al final tendrás en tu carpeta personal un proyecto Kotlin Multiplatform en la carpeta Pokedex-KMP, con dos módulos de Gradle, un proyecto de Xcode, la vista de Android Studio adecuada para trabajar con él y las versiones exactas que usa el curso. En la siguiente le das forma al módulo compartido y compruebas que compila y pasa sus tests en Android, en iOS y en la JVM.
No vas a escribir el proyecto a mano. Lo genera el asistente de Android Studio (el plugin de JetBrains para Kotlin Multiplatform), y después lo llevas a las versiones del curso: el asistente pone las que conocía el día que se publicó, y las del curso son otras. Antes hay un paso previo: comprobar que el plugin de Kotlin Multiplatform está en Android Studio.
Paso 1 · Comprueba el plugin de Kotlin Multiplatform
Objetivo: que el menú de nuevo proyecto de Android Studio ofrezca la plantilla Kotlin Multiplatform.
Un plugin del IDE es un complemento que le enseña al editor algo nuevo, igual que una extensión en el navegador. (No lo confundas con los plugins de Gradle de la lección Los ficheros de Gradle de tu proyecto: aquellos enseñan a Gradle a compilar; este enseña a Android Studio a crear y a ejecutar proyectos Kotlin Multiplatform.) Android Studio puede traerlo ya instalado o no; si no está, se instala una vez. Primero mira si lo tienes: en File → New → New Project… (o en el botón New Project de la pantalla de bienvenida), la lista Phone and large screens (teléfonos y pantallas grandes) termina con la plantilla Kotlin Multiplatform, con el icono de una K morada. Si ya está, pasa al paso 2. Si no está, instálalo:
- Abre los ajustes: en macOS, Android Studio → Settings… (atajo Cmd+,).
- En la lista de la izquierda, pulsa Plugins.
- Arriba, elige la pestaña Marketplace (la tienda de plugins) y escribe
Kotlin Multiplatformen el buscador. - En el resultado Kotlin Multiplatform (el de JetBrains), pulsa Install.
- Al terminar, el botón cambia a Restart IDE: púlsalo y confirma. Android Studio se cierra y se vuelve a abrir.
Comprueba que quedó instalado. Vuelve a File → New → New Project…: al final de la lista, debajo de Native C++ y Game Activity, aparece Kotlin Multiplatform. Si no la ves, vuelve a Settings → Plugins, pestaña Installed, y comprueba que Kotlin Multiplatform está en la lista y activado.
Paso 2 · Abre el asistente y rellena las dos pantallas
Objetivo: un proyecto nuevo en ~/Pokedex-KMP, es decir, una carpeta Pokedex-KMP dentro de tu carpeta personal.
En Android Studio: File → New → New Project…. A la izquierda elige la categoría Phone and large screens y, al final de la lista de plantillas, Kotlin Multiplatform. Pulsa Next. Abajo hay cuatro botones: Cancel (cancelar), Previous (volver), Next (siguiente) y Finish (terminar).
Los nombres de las pantallas están en inglés, tal como los verás en el IDE; la primera vez va su traducción entre paréntesis. La primera pantalla («Generate a Kotlin Multiplatform project») pide cinco datos:
- Name (nombre):
Pokedex. El nombre del proyecto, el que verán Gradle y Xcode. Trae uno por defecto («My Application»): bórralo. - Package name (nombre del paquete):
com.sebastiannarvaez.pokedex, tal cual. Es el identificador de la app, que la distingue de las demás en un móvil (mira el aviso de abajo): lo que escribes aquí se convierte en elapplicationIdde la app de Android. Elnamespacees otra cosa y se ajusta en la lección siguiente. Al cambiar el nombre, el asistente puede reescribirlo: comprueba que queda exactamente así. - Save location (dónde se guarda): la carpeta del proyecto. Por defecto trae una carpeta con el nombre que escribiste. Cámbiala: en este curso el proyecto es siempre
~/Pokedex-KMP.~es el atajo de la Terminal para «tu carpeta personal», que en un Mac es/Users/tu-usuario. En el campo, escribe/Users/tu-usuario/Pokedex-KMP(cambiatu-usuariopor el tuyo) o pulsa el icono de carpeta y elígela. Desde ahora, cuando una lección digacd ~/Pokedex-KMP, es esta carpeta. - Minimum SDK (la versión de Android más antigua en la que funcionará la app): deja API 24 («Nougat», Android 7.0), que es la que trae por defecto y la que usa este curso. Debajo, el IDE te dice qué porcentaje de móviles la ejecutan; el enlace «Help me choose» (ayúdame a elegir) no hace falta.
- Build configuration language (el lenguaje de los ficheros que configuran la compilación): Kotlin DSL (build.gradle.kts) [Recommended], como en Marcador.
Pulsa Next. La segunda pantalla lleva el mismo título que la primera, «Generate a Kotlin Multiplatform project», así que no pienses que se repitió: lo que cambia es lo que pide, las plataformas para las que se genera el proyecto:
- Android: márcala. Trae su interfaz con Jetpack Compose.
- iOS: márcala. Al marcarla aparece un desplegable, UI Implementation (cómo se escribe la interfaz de iOS). Despliégalo: trae marcada la opción Share UI (Compose Multiplatform), que reutiliza la interfaz de Android en iOS. Esa no. En el desplegable, elige la otra, la de SwiftUI: la que no comparte la interfaz con Android (si la etiqueta incluye algo como «Do not share UI», es esa; el texto exacto cambia según la versión del plugin, así que guíate por lo que significa).
- Desktop (aplicación de escritorio), Web y Server (un servidor): déjalas sin marcar. El curso no los usa.
- Include tests (incluir tests): déjala marcada. Crea carpetas de pruebas que usaremos más adelante.
En esta pantalla verás también un enlace «Install Kotlin Toolchain plugin»: no lo uses. Más abajo se explica por qué.
Pulsa Finish y espera: Android Studio genera los ficheros y puede preguntar si abre el proyecto en esta ventana o en una nueva (elige This Window) y si confías en el proyecto (Trust Project: pulsa Trust Project, es tu propio proyecto). Después lanza la primera sincronización de Gradle (barra de progreso abajo; varios minutos la primera vez, y necesita internet).
SwiftUI sin compartir la interfaz es la decisión de fondo del curso: la lógica se comparte, la interfaz se escribe dos veces, nativa en cada plataforma. Obliga a que Kotlin y Swift se hablen de verdad, que es justo lo que queremos aprender.
Qué es Kotlin Toolchain (y por qué elegimos Gradle)
Un sistema de compilación es el programa que convierte tu código en una app: descarga las librerías, compila, ejecuta los tests y empaqueta el resultado. Ya conoces uno, Gradle, de Marcador.
El asistente menciona otra opción, Kotlin Toolchain, de JetBrains. Está en Alpha (todavía cambia y puede fallar). Ofrece un solo comando, kotlin, para crear, compilar, ejecutar y probar un proyecto, se configura con ficheros module.yaml en lugar de los de Gradle y se instala con su propio plugin del IDE. Es una alternativa a Gradle.
El curso usa Gradle por tres razones:
- Es el estándar actual.
- Las lecciones, las librerías y los plugins se escriben para Gradle.
- Kotlin Toolchain aún está en Alpha.
Por eso, en la segunda pantalla del asistente, el enlace «Install Kotlin Toolchain plugin» no hay que usarlo: déjalo como está.
Paso 3 · Cambia a la vista Project
Objetivo: que el panel de la izquierda muestre las carpetas reales del proyecto.
Cuando el proyecto termina de generarse, el panel de la izquierda muestra por defecto la vista Android, la que usaste en Marcador. Para un proyecto Kotlin Multiplatform se queda corta: muestra los módulos, pero agrupa y mezcla los source sets (las carpetas por plataforma, como commonMain o iosMain) y no muestra iosApp, que no es un módulo de Gradle. Aquí esas carpetas son lo importante. En Marcador bastaba porque era una app solo de Android. Cámbiala una vez:
- Arriba del panel, hay un selector con la palabra Android (o Project) y una flecha. Pulsa la flecha.
- Elige Project.
Ahora el panel enseña las carpetas tal como están en el disco. Desde ahora, las lecciones de la Pokédex dan las rutas así (androidApp/src/main/kotlin/…, shared/src/commonMain/kotlin/…, gradle/libs.versions.toml): son las carpetas que ves en la vista Project.
Una cosa más: el código de la Pokédex va en inglés, como el de un equipo real, y se organiza por funcionalidad (cada pantalla con sus carpetas data, domain y ui). En Marcador el código iba en español para que pudieras leerlo como si fuera la guía; las carpetas de Marcador siguen el mismo criterio, con nombres de Google.
Si ya sabes qué vista quieres, las dos opciones del selector se llaman igual en el menú que en el panel: Project es la de las carpetas reales.
Paso 4 · Mira lo que acaba de aparecer
Objetivo: saber qué es cada carpeta y cada fichero que creó el asistente, sin tocar ninguno.
Tres carpetas de código (shared, androidApp e iosApp) y un puñado de ficheros de configuración. Ya conoces la idea de módulo de Tu primer proyecto en Kotlin: una parte del proyecto que Gradle compila por separado.
Hay también una carpeta .idea (los ajustes de Android Studio para este proyecto). Tres cosas del árbol que el asistente crea y el curso no usa, o usa más adelante: proguard-rules.pro y gradle-daemon-jvm.properties, y las carpetas de tests androidHostTest e iosTest (no las usamos ahora). Ninguno hace falta tocarlo, y el resto (README.md, local.properties y otros ficheros del asistente) también se queda tal cual. No borres nada.
iosApp es un proyecto de Xcode: Android Studio no lo trata como un módulo de Gradle, y lo abrirás con Xcode en Ejecutar en iOS. Los títulos de los bloques de código de estas lecciones llevan la ruta del disco, que es la que muestra el árbol de arriba; para abrir un fichero, despliega sus carpetas en el panel (vista Project) hasta llegar a él.
Un recorrido corto, una línea por fichero. Los vas a leer línea a línea en Anatomía del proyecto; hoy basta con saber qué es cada uno.
iosApp/Configuration/Config.xcconfig: los ajustes de la app de iOS que cambian de una persona a otra.TEAM_IDes el identificador del equipo de desarrollo con el que Apple firma tus apps (el Team que elegiste en Tu primera app de iOS). Hace falta para instalar en un iPhone de verdad; para el simulador puede quedar vacío, y hoy no lo tocas.settings.gradle.kts(en la raíz): dice qué módulos existen (include(":shared"),include(":androidApp")) y de dónde se descargan las librerías. Es el primer fichero que lee Gradle. Si quitas la líneainclude(":shared"), Gradle deja de saber que ese módulo existe.build.gradle.kts(el de la raíz): no construye nada: declara qué plugins existen para que cada módulo los aplique.gradle.properties: paresclave=valorque cambian cómo trabaja Gradle. Hoy no cambia.gradle/wrapper/gradle-wrapper.properties:./gradlewdescarga la versión exacta de Gradle que pide el proyecto, así que todos compilan igual; la versión está en una línea de este fichero.shared/build.gradle.ktsyandroidApp/build.gradle.kts: la ficha de cada módulo. La del compartido declara los destinos del código compartido (los toca la lección siguiente); la deandroidAppdice cómo se construye la app de Android (su paquete, suapplicationId, y que usa Compose y el móduloshared). ElapplicationIdes la identidad de la app dentro del móvil; no es el paquete donde vive el código (elnamespace). La diferencia está en Gradle: ficheros, catálogo y dependencias y la usarás en la lección siguiente.
Hay algo de settings.gradle.kts que conviene digerir ya, porque es la primera cosa rara de KMP: Gradle no sabe que existe una app de iOS. Lo que Gradle produce es un framework (el paquete de código ya compilado que Xcode une a la app); quien lo consume es Xcode. Cómo se conectan los dos es la lección Integración con iOS.
El catálogo: comprueba tus claves
El fichero que vas a tocar es ese catálogo. Ábrelo: gradle/libs.versions.toml (vista Project, carpeta gradle). Tiene tres secciones, cada una con su cabecera: [versions], [libraries] y [plugins].
Antes, una distinción que te hará falta. Una app es lo que se instala en el móvil; una librería es código que usan otras. shared es una librería: código que usan las dos apps (la de Android y la de iOS). Por eso el proyecto lleva un plugin de Android para apps y otro para librerías.
Tu única tarea ahora: en [plugins], apunta cómo se llaman tus plugins de Kotlin Multiplatform y de Android para librerías (en el curso, kotlinMultiplatform y androidKmpLibrary), porque en la lección siguiente los comparas con el fichero del módulo compartido. Si una clave se llama distinto (un plugin kotlin-multiplatform en vez de kotlinMultiplatform), usa la tuya: en el código los guiones se vuelven puntos (libs.plugins.kotlin.multiplatform).
No borres ninguna clave del catálogo, y no añadas ahora las que falten: si una lección necesita una, te da la línea.
Paso 5 · Las versiones, al stack del curso
Objetivo: que kotlin, agp y Gradle valgan lo que usa el curso y que Sync Now termine sin rojo.
El asistente pone las versiones que conocía el día que se publicó. Las llevamos a las del curso, todas estables y publicadas en el repositorio Maven (el almacén público de librerías, que se consulta como en La primera dependencia): Kotlin 2.4.20, AGP 9.4.0 y Gradle 9.7.1 en el wrapper.
Esto no es cosmética. El plugin de Kotlin, el de AGP y el compilador de Compose (el plugin que traduce los composables) van acoplados: si subes uno y dejas otro atrás, el proyecto deja de sincronizar o de compilar; a veces el mensaje dice qué versión falta y a veces no, así que pon exactamente estas.
No pegues este bloque encima del tuyo: cambia solo los números de las claves que ya tienes en [versions]. kotlin y agp deben valer exactamente lo de abajo (los usan los plugins). En las demás, pon el número de abajo si el tuyo es más antiguo; si ya tienes uno más nuevo, déjalo. (Los números se comparan uno a uno, de izquierda a derecha: 1.13 es más nuevo que 1.9. Si dudas, pon exactamente los de abajo.) Si una clave de abajo no existe en tu catálogo, no la añadas ahora; si una lección la necesita, te dará la línea:
[versions]
kotlin = "2.4.20" # el compilador de Kotlin; lo usan también los plugins de Kotlin y de Compose
agp = "9.4.0" # el Android Gradle Plugin
androidCompileSdk = "37" # contra qué API de Android se compila
androidMinSdk = "24" # el Android más antiguo donde se instala (Android 7.0)
androidTargetSdk = "37" # la versión de Android para la que está pensada la app
coreKtx = "1.19.0" # una versión por librería de AndroidX
activityCompose = "1.13.0"
composeBom = "2026.08.00" # el BOM de Compose: una lista de versiones que encajan entre sí
lifecycle = "2.11.0"Y el wrapper, que fija qué Gradle usa el proyecto sin depender de lo que tengas instalado. Ábrelo en gradle/wrapper/gradle-wrapper.properties y cambia la línea distributionUrl solo si dice otra versión:
distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.1-bin.zipLa barra \ delante de : es como este fichero escribe los dos puntos: déjala.
Pulsa Sync Now cuando Android Studio lo ofrezca (Gradle relee la configuración y descarga lo nuevo; debe terminar sin rojo). Si sale en rojo, un número que no existe o una clave mal escrita son lo más probable: la caja «Si Sync sale en rojo» de Los ficheros de Gradle de tu proyecto lista los fallos más habituales. Si Sync dice que falta «Android SDK Platform 37», acepta que Android Studio la instale (o instálala desde el SDK Manager que usaste en Instalar Android Studio y el SDK).
Con esto el proyecto tiene las versiones del curso y sincroniza. Todavía no vas a compilar: el módulo compartido se queda como lo dejó el asistente hasta la lección siguiente, El módulo compartido y la prueba de humo.
Punto de control
- File → New → New Project… ofrece la plantilla Kotlin Multiplatform (si no, Settings → Plugins → Installed debe listar el plugin y estar activado).
- Tu proyecto está en
~/Pokedex-KMPy el selector del panel de la izquierda dice Project. - En esa vista ves, en el primer nivel, las carpetas
androidApp,gradle,iosAppyshared, y en la raízsettings.gradle.kts,build.gradle.ktsygradle.properties; dentro deshared/srcestáncommonMain,androidMaineiosMain. - En
gradle/libs.versions.toml,kotlinvale"2.4.20"yagpvale"9.4.0". - En
gradle/wrapper/gradle-wrapper.properties, la líneadistributionUrltermina engradle-9.7.1-bin.zip. - Sync Now termina sin rojo.
Comprueba lo que entendiste
5 preguntas · necesitas 4 para completar la lección
1.¿Por qué
settings.gradle.ktssolo incluye:sharedy:androidApp, y no:iosApp?2.Abres File → New → New Project… y la lista de plantillas no incluye Kotlin Multiplatform. ¿Qué haces?
3.Subes
agpa una versión más nueva que la del curso y dejaskotlincomo estaba. Al sincronizar, Gradle falla. ¿Cuál es la causa más probable?4.¿Qué fija
gradle-wrapper.properties?5.¿Por qué cambias el panel de la izquierda a la vista Project al empezar la Pokédex?