¿Qué es Kotlin Multiplatform Mobile (KMM), y qué compartirías realmente entre iOS y Android con él?
KMM no es un framework de UI disfrazado: compila un solo source set de Kotlin a código nativo real en ambas plataformas, y la respuesta honesta es qué tan acotado está pensado ese límite de lo compartido.
APRENDE HACIENDOPon a prueba tu intuición3 pasos
¿Qué es Kotlin Multiplatform Mobile (KMM), y qué compartirías realmente entre iOS y Android con él?
Usa los ejemplos y la explicación de la lección para comprobar tu idea.
Reflexión personal. No se envía a ningún servicio de IA.Esta pregunta evalúa si el candidato entiende KMM como una herramienta puntual para un problema específico — lógica de negocio duplicada entre dos código base nativos — y no como "Flutter con Kotlin". Esa distinción importa, porque el alcance honesto de KMM es mucho más acotado que el de un framework de UI multiplataforma completo, y saber exactamente dónde está ese límite es la respuesta senior.
#Qué es KMM en realidad
Kotlin Multiplatform Mobile te permite escribir Kotlin una sola vez en un source set commonMain y compilarlo a dos targets distintos: bytecode de JVM para Android (corre exactamente como cualquier otro módulo Android) y un binario nativo vía Kotlin/Native, compilado ahead-of-time a través de LLVM en un .framework que Xcode enlaza como cualquier otro framework de Objective-C/Swift. No hay intérprete ni bridge en runtime en ninguno de los dos lados — cada plataforma recibe código nativo real y compilado para la lógica compartida.
El código que necesita una implementación específica por plataforma se declara con expect en commonMain y se implementa con actual en cada source set de plataforma:
// commonMainexpect fun getPlatformName(): Stringclass Greeting {fun greet(): String = "Hello from ${getPlatformName()}"}
// androidMainactual fun getPlatformName(): String = "Android"
// iosMainactual fun getPlatformName(): String = "iOS"
#Qué compartís en la práctica — y qué nunca compartís
Las partes de una app que son genuinamente lógica independiente de la plataforma son las que vale la pena compartir: networking (típicamente el cliente Ktor), manejo de JSON (kotlinx.serialization), la capa de dominio/reglas de negocio, persistencia local (SQLDelight, que genera Kotlin tipado a partir de SQL y compila al driver de base de datos nativo de cada plataforma), el cableado de inyección de dependencias (Koin funciona bien en multiplataforma) y lógica de validación. Un repositorio compartido se ve como Kotlin común y corriente:
// commonMain@Serializabledata class User(val id: String, val name: String)class UserRepository(private val client: HttpClient) {suspend fun fetchUser(id: String): User =client.get("https://api.example.com/users/$id").body()}
Lo que deliberadamente no se comparte es la UI. Android mantiene Jetpack Compose, iOS mantiene SwiftUI (o UIKit); la UI de cada plataforma se escribe de forma nativa, a propósito, para que la app conserve rendimiento nativo, las convenciones nativas de la plataforma, y acceso a las APIs de plataforma más nuevas desde el día uno sin esperar a que un framework multiplataforma se ponga al día. El trabajo de KMM termina en la capa de datos y dominio.
#La parte que hace tropezar a la gente: las coroutines cruzando a Swift
Una clase con forma de ViewModel compartida que expone estado con coroutines y StateFlow funciona bien del lado de Kotlin:
class UserViewModel(private val repo: UserRepository) {private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())private val _state = MutableStateFlow<UiState>(UiState.Loading)val state: StateFlow<UiState> = _state.asStateFlow()fun load(id: String) {scope.launch {_state.value = UiState.Loading_state.value = runCatching { repo.fetchUser(id) }.fold(UiState::Loaded, UiState::Error)}}}
El problema es que Swift no tiene un concepto nativo de coroutine de Kotlin ni de Flow, así que un suspend fun crudo o un StateFlow expuesto a iOS es incómodo de consumir tal cual. La mayoría de los equipos recurre a una librería de bridging (SKIE o KMP-NativeCoroutines son las opciones habituales) que genera funciones async/await amigables para Swift y wrappers de AsyncSequence sobre la API de coroutines de Kotlin, en vez de escribir a mano wrappers con completion handlers para cada función suspendida.
🧠 Límites de lo compartido en KMM
0/2 · 0/2 answered1. ¿A qué compila KMM el código de commonMain para el target de iOS?
2. ¿Qué capa típicamente NO comparte un setup de KMM entre iOS y Android?