1. Antes de comenzar
Requisitos previos
- Saber cómo compilar apps con Jetpack Compose
- Experiencia con Kotlin
- Conocimientos básicos de la sintaxis de Swift
Requisitos
- La versión estable más reciente de Android Studio (Meerkat o una posterior)
- Un sistema macOS con Xcode 16.1 y el simulador de iPhone con iOS 16.0 o una versión posterior
Qué aprenderás
- Los conceptos básicos de Kotlin Multiplatform
- Cómo compartir código entre plataformas
- Cómo conectar el código compartido en iOS y Android
2. Prepárate
Para comenzar, sigue estos pasos:
- Clona el repositorio de GitHub:
$ git clone https://github.com/android/codelab-android-kmp.git
También tienes la opción de descargar el repositorio como archivo ZIP:
- En Android Studio, abre el proyecto
get-started
, que contiene las siguientes ramas:
main
: Contiene el código de partida para este proyecto, en el que realizarás cambios para completar el codelab.end
: Contiene el código de la solución de este codelab.
Este codelab comienza con la rama main
. Puedes seguir el codelab paso a paso a tu propio ritmo.
- Si quieres ver el código de la solución, ejecuta este comando:
$ git clone -b end https://github.com/android/codelab-android-kmp.git
También puedes descargar el código de la solución:
Instala Xcode
Para compilar y ejecutar la parte de iOS de este codelab, necesitas Xcode y un simulador de iOS:
- Instala Xcode desde App Store de Mac (para ello, necesitas una cuenta de Apple).
- Una vez que se instale, inicia Xcode.
- Aparecerá un diálogo que indicará qué componentes están integrados y cuáles debes descargar.
- Comprueba si tienes iOS 18.4 (o una versión posterior).
- Haz clic en Download & Install.
- Espera a que se instalen los componentes.
Este codelab se probó con Xcode 16.3. Si usas cualquier otra versión de Xcode y tienes problemas, te recomendamos que descargues la versión exacta que se menciona en este codelab.
La app de ejemplo
Esta base de código contiene una app para Android compilada con Jetpack Compose y una app para iOS compilada con SwiftUI. El proyecto de Android se encuentra en la carpeta androidApp/
, mientras que el proyecto de iOS se encuentra en la carpeta iosApp/
, que también contiene el KMPGetStartedCodelab.xcodeproj
para ejecutar con Xcode.
3. Introducción a Kotlin Multiplatform
Kotlin Multiplatform (KMP) te permite escribir código una vez y compartirlo en varias plataformas de destino, como Android, iOS, la Web y computadoras de escritorio. Si aprovechas KMP, puedes minimizar la duplicación de código, mantener la coherencia y reducir significativamente el tiempo y el esfuerzo de desarrollo.
KMP no dicta cuánto ni qué partes de tu base de código debes compartir. Tú decides qué partes del código vale la pena compartir.
Decide qué compartir
El código compartido te permite mantener la coherencia y reducir la duplicación en todas las plataformas. Muchos equipos de desarrollo de apps para dispositivos móviles comienzan por compartir un conjunto discreto de lógica empresarial (p. ej., acceso a la base de datos, acceso a la red, etc.) y las pruebas asociadas, y, luego, comparten código adicional con el tiempo.
Muchas bibliotecas de Android Jetpack son compatibles con KMP. Las bibliotecas de Jetpack que se convirtieron en multiplataforma ofrecen varios niveles de compatibilidad según la plataforma de destino. Para obtener la lista completa de las bibliotecas y sus niveles de compatibilidad, consulta la documentación.
Por ejemplo, una de las bibliotecas compatibles, la biblioteca de bases de datos Room, es compatible con Android, iOS y computadoras de escritorio. Esto te permite portar la creación de la base de datos y su lógica relacionada a un módulo compartido de KMP común y, al mismo tiempo, conservar el otro código nativo en ambas plataformas.
Un posible paso después de migrar la base de datos sería compartir otra lógica de dominio. Luego, también puedes considerar usar la biblioteca multiplataforma ViewModel
de Android Jetpack.
Cómo escribir código específico de la plataforma
Kotlin Multiplatform presenta nuevas técnicas para implementar funciones específicas de la plataforma.
Declaraciones esperadas y reales
La función del lenguaje Kotlin expect
actual
está diseñada para admitir la base de código multiplataforma de Kotlin con compatibilidad total con IDE.
Este enfoque es ideal cuando el comportamiento específico de la plataforma se puede encapsular en una sola función o clase. Es un mecanismo flexible y potente. Por ejemplo, una clase expect
común puede tener contrapartes actual
específicas de la plataforma con modificadores de visibilidad más abiertos, supertipos adicionales o diferentes tipos o modificadores de parámetros. Estos tipos de variantes no serían posibles con una API de interfaz estricta. Además, expect
actual
se resuelve de forma estática, lo que significa que la implementación específica de la plataforma se aplica de manera forzosa en el tiempo de compilación.
Interfaz e implementaciones en Kotlin
Si ambas plataformas deben seguir APIs similares, pero con implementaciones diferentes, puedes definir una interfaz en el código compartido como alternativa a las declaraciones esperadas y reales. Este enfoque te permite usar diferentes implementaciones de pruebas o cambiar a una implementación diferente durante el tiempo de ejecución.
Además, las interfaces no requieren conocimientos específicos de Kotlin, lo que hace que esta opción sea accesible para los desarrolladores que estén familiarizados con las interfaces en otros lenguajes.
Interfaz en código compartido común, implementación en código nativo (Android o Swift)
En algunos casos, debes escribir código que no está disponible en el código de KMP. En esta situación, puedes definir una interfaz en código compartido, implementarla para Android en Kotlin y proporcionar una contraparte de iOS en Swift. Por lo general, las implementaciones nativas se insertan en el código compartido, ya sea usando la inserción de dependencias o directamente. Esta estrategia permite una experiencia personalizada en cada plataforma y, al mismo tiempo, mantiene una interfaz común para el código compartido.
4. Abre el proyecto de Xcode desde Android Studio
Una vez que se instale Xcode, debes asegurarte de poder ejecutar la app para iOS.
Puedes abrir el proyecto para iOS directamente desde Android Studio.
- Cambia el panel Project para usar la vista de proyecto.
- Busca el archivo KmpGetStartedCodelab.xcodeproj en la carpeta [root]/iosApp/.
- Haz clic con el botón derecho en el archivo y selecciona Open In y Open in Associated Application. Se abrirá la app para iOS en Xcode.
- Para ejecutar el proyecto en Xcode, haz clic en ⌘+R o navega al menú Product y selecciona Run.
5. Agrega un módulo de KMP
Para agregar compatibilidad con KMP a tu proyecto, primero crea un módulo shared
para el código que se reutilizará en todas las plataformas (iOS y Android).
Android Studio proporciona una forma de agregar un módulo de Kotlin Multiplatform con su plantilla de módulo compartido de KMP.
Para crear el módulo de KMP, haz lo siguiente en Android Studio:
- Navega a File > New > New Module > Kotlin Multiplatform Shared Module.
- Cambia el paquete por
com.example.kmp.shared
. - Haz clic en Finish
.
- Una vez que se complete la creación del módulo y Gradle termine de sincronizarse, aparecerá un nuevo módulo
shared
en el proyecto. Para ver la vista que se muestra a continuación, es posible que debas cambiar de la vista de Android a la vista de proyecto.
El módulo compartido que genera la plantilla de módulo compartido de KMP incluye algunas funciones y pruebas básicas de marcadores de posición. Estos marcadores de posición garantizan que el módulo se compile y ejecute correctamente desde el principio.
Importante: Ten en cuenta la diferencia entre la carpeta iosApp y la carpeta iosMain. La carpeta iosApp contiene el código independiente de la app para iOS, mientras que iosMain forma parte del módulo compartido de KMP que acabas de agregar. iosApp contiene código Swift, mientras que iosMain contiene código KMP específico de la plataforma de iOS.
Vincula el módulo compartido a la app para Android
Primero, debes vincular el nuevo módulo compartido como una dependencia en el módulo de Gradle :androidApp
para permitir que la app use el código compartido:
- Abre el archivo
androidApp/build.gradle.kts
. - Agrega la dependencia del módulo
shared
en el bloque de dependencias de la siguiente manera:
dependencies {
...
implementation(projects.shared)
}
- Sincroniza el proyecto con los archivos de Gradle
.
Verifica el acceso de código al módulo shared
Para verificar que la app para Android pueda acceder al código del módulo shared
, realizaremos una actualización simple de la app.
- En el proyecto KMPGetStartedCodelab, abre el archivo
MainActivity
enandroidApp/src/main/java/com/example/kmp/getstarted/android/MainActivity.kt
. - Modifica el elemento componible
Text
de contenido para incluir la información deplatform()
en la cadena que se muestra.
Text(
"Hello ${platform()}",
)
- Haz clic en
⌥(option)+return
en el teclado y seleccionaImport function 'platform'
.
- Compila y ejecuta la app en un dispositivo Android o en un emulador.
Esta actualización verifica si la app puede llamar a la función platform()
desde el módulo shared
, que debería mostrar "Android"
cuando se ejecuta en la plataforma de Android.
6. Configura el módulo compartido en la app para iOS
Swift no puede usar módulos de Kotlin directamente como lo hacen las apps para Android y requiere que se produzca un framework binario compilado (paquete XCFramework). Un paquete XCFramework es un paquete binario que incluye los frameworks y las bibliotecas necesarios para compilar para varias plataformas de Apple.
Cómo se distribuye la biblioteca compartida
La nueva plantilla de módulo en Android Studio ya configuró el módulo compartido para producir un framework para cada una de las arquitecturas de iOS. Puedes encontrar el siguiente código en el archivo build.gradle.kts
del módulo shared
.
val xcfName = "sharedKit"
iosX64 {
binaries.framework {
baseName = xcfName
}
}
iosArm64 {
binaries.framework {
baseName = xcfName
}
}
iosSimulatorArm64 {
binaries.framework {
baseName = xcfName
}
}
Vincula la biblioteca compartida en el proyecto de iOS
Este paso implica configurar Xcode para ejecutar una secuencia de comandos que genere el framework de Kotlin y llamar a la función platform()
en la app para iOS.
Para consumir la biblioteca compartida, debes conectar el framework de Kotlin al proyecto de iOS con los siguientes pasos:
- Abre el proyecto de iOS (el directorio
iosApp
mencionado anteriormente) en Xcode y haz doble clic en el nombre del proyecto en el navegador de proyectos para abrir la configuración del proyecto.
- En la pestaña Build Phases de la configuración del proyecto, haz clic en + y selecciona New Run Script Phase. De esta manera, se agrega una nueva fase "Run script" después de todas las demás.
- Haz doble clic en el título Run Script para cambiarle el nombre. Cambia el nombre predeterminado Run Script a Compile Kotlin Framework para que se comprenda lo que hace esta fase.
- Despliega la fase de compilación y, en el campo de texto debajo de Shell, ingresa el código de la secuencia de comandos:
cd "$SRCROOT/.."
./gradlew :shared:embedAndSignAppleFrameworkForXcode
- Arrastra la fase Compile Kotlin Framework antes de la fase Compile Sources.
- Para compilar el proyecto en Xcode, haz clic en ⌘+B o navega al menú Product y selecciona Build. Ten en cuenta que el progreso de la compilación se muestra en la parte superior de Xcode.
Si todo está bien configurado, el proyecto se compilará de forma correcta.
Configurar la fase de compilación de la secuencia de comandos de ejecución de esta manera te permite compilar tu proyecto de iOS desde Xcode sin necesidad de cambiar a una herramienta diferente para compilar el módulo compartido.
Verifica el acceso de código al módulo shared
Para verificar que la app para iOS pueda acceder correctamente al código del módulo shared
, realizarás la misma actualización sencilla que hiciste para la app para Android.
- En el proyecto de iOS, en Xcode, abre el archivo
ContentView.swift
enSources/View/ContentView.swift
. - Agrega
import sharedKit
en la parte superior del archivo. - Modifica la vista
Text
para incluir la información dePlatform_iosKt.platform()
en la cadena que se muestra con\(Platform_iosKt.platform())
.
Este es el resultado final del archivo:
import SwiftUI
import sharedKit
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, \(Platform_iosKt.platform())!")
}
.padding()
}
}
- Para ejecutar la app, haz clic en ⌘ + R o navega al menú Product, y haz clic en Run.
Esta actualización verifica si la app para iOS puede llamar a la función platform()
desde el módulo compartido, que debería mostrar "iOS"
cuando se ejecuta en la plataforma de iOS.
7. Agrega la herramienta Swift/Kotlin Interface Enhancer (SKIE)
De forma predeterminada, la interfaz nativa que produce Kotlin es un encabezado de Objective-C. Swift es directamente compatible con Objective-C, pero este último no incluye todas las funciones modernas de Swift ni Kotlin.
Esta también es la razón por la que, en el ejemplo anterior, no podías usar la llamada a platform()
directamente en el código Swift. KMP no puede generar una función global porque Objective-C no admite funciones globales, solo funciones estáticas encapsuladas en una clase, por lo que debes agregar Platform_iosKt
.
Para que la interfaz sea más compatible con Swift, puedes usar la herramienta Swift/Kotlin Interface Enhancer (SKIE) para mejorar la interfaz de Swift del módulo :shared
.
Las características comunes de SKIE son las siguientes:
- Mayor compatibilidad con los argumentos predeterminados
- Mayor compatibilidad con jerarquías selladas (
sealed class
ysealed interface
) - Mayor compatibilidad con
enum class
con control exhaustivo en las sentenciasswitch
- Interoperabilidad entre
Flow
yAsyncSequence
- Interoperabilidad entre
suspend fun
yasync func
- Agrega el complemento de Gradle
co.touchlab.skie
al archivolibs.versions.toml
:
[versions]
skie = "0.10.1"
[plugins]
skie = { id = "co.touchlab.skie", version.ref = "skie" }
- Agrega el complemento al archivo
build.gradle.kts
raíz.
plugins {
...
alias(libs.plugins.skie) apply false
}
- Agrega el complemento al archivo
build.gradle.kts
del módulo:shared
:
plugins {
...
alias(libs.plugins.skie)
}
- Sincroniza el proyecto con Gradle
Quita la llamada a la función estática
Ahora, cuando vuelvas a compilar la app para iOS, es posible que no notes nada de inmediato, pero puedes quitar el prefijo Platform_iosKt
y permitir que la función platform()
actúe como una función global.
Text("Hello, KMP! \(platform())")
Esto funciona porque SKIE (entre otras funciones) aprovecha las Notas de la API de Swift, que agregan información sobre las APIs para consumirlas mejor desde el código Swift.
8. Felicitaciones
Felicitaciones. Agregaste el primer código de Kotlin Multiplatform compartido a proyectos de iOS y Android. Si bien este es solo un punto de partida mínimo, ahora puedes comenzar a descubrir funciones y casos de uso más avanzados para compartir código con KMP.
¿Qué sigue?
Aprende a usar Jetpack Room para compartir una capa de datos entre iOS y Android en el siguiente codelab.
Más información
- Obtén información sobre qué bibliotecas de Jetpack admiten KMP.
- Consulta la documentación oficial de Kotlin Multiplatform.