Internacionalización (i18n) en Kotlin: Guía completa con ejemplos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Internacionalización (i18n) en Kotlin: Guía completa con ejemplos

\n\n

La internacionalización (i18n) es el proceso de diseñar y desarrollar software para que pueda adaptarse a diferentes idiomas y regiones sin realizar cambios en el código fuente. En el ecosistema de Kotlin, ya sean aplicaciones Android, proyectos de servidor con Ktor o soluciones multiplataforma con Kotlin Multiplatform, la implementación correcta de i18n es fundamental para el éxito global del producto. En este artículo, exploraremos los enfoques principales, las herramientas y las mejores prácticas para la internacionalización de aplicaciones Kotlin.

\n\n

¿Por qué es importante i18n en Kotlin?

\n

Kotlin, al ser un lenguaje moderno totalmente compatible con Java, hereda todas las capacidades de Java para la localización, pero también ofrece sus propias soluciones únicas. Una internacionalización adecuada permite:

\n
    \n
  • Ampliar significativamente la audiencia de su aplicación
  • \n
  • Mejorar la experiencia del usuario para hablantes de diferentes idiomas
  • \n
  • Cumplir con los requisitos legales de diferentes países (por ejemplo, relacionados con monedas o formatos de fecha)
  • \n
  • Simplificar el proceso de agregar nuevos idiomas en el futuro
  • \n
\n\n

Enfoques principales para i18n en Kotlin

\n

1. Uso de Resource Bundle (enfoque compatible con Java)

\n

La forma más común y sencilla es utilizar los estándares ResourceBundle y archivos de propiedades (.properties). Este método es ideal para aplicaciones de consola y proyectos de servidor en Kotlin.

\n\n
// messages_en.properties\ngreeting=Hello, {0}!\nfarewell=Goodbye\n\n// messages_ru.properties\ngreeting=Привет, {0}!\nfarewell=До свидания
\n\n
import java.util.ResourceBundle\nimport java.text.MessageFormat\n\nfun main() {\n    val bundle = ResourceBundle.getBundle("messages", Locale("ru"))\n    val greeting = MessageFormat.format(bundle.getString("greeting"), "Мир")\n    println(greeting) // Выведет: Привет, Мир!\n    \n    println(bundle.getString("farewell")) // Выведет: До свидания\n}
\n\n

2. Enfoque específico de Kotlin con funciones de extensión

\n

Kotlin permite crear una API más concisa y segura para trabajar con localización, utilizando funciones de extensión y propiedades delegadas.

\n\n
import java.util.*\nimport kotlin.properties.ReadOnlyProperty\nimport kotlin.reflect.KProperty\n\nclass I18n(private val baseName: String) {\n    private val bundle: ResourceBundle\n        get() = ResourceBundle.getBundle(baseName)\n    \n    operator fun provideDelegate(\n        thisRef: Any?, \n        prop: KProperty<*>\n    ): ReadOnlyProperty {\n        return ReadOnlyProperty { _, _ -> bundle.getString(prop.name) }\n    }\n}\n\nobject Strings {\n    val i18n = I18n("messages")\n    \n    val greeting by i18n\n    val farewell by i18n\n}\n\nfun main() {\n    // Utiliza automáticamente la configuración regional del sistema\n    println(Strings.greeting) // Выведет соответствующее значение из файла свойств\n    println(Strings.farewell)\n}
\n\n

Herramientas para la localización en Kotlin

\n

1. Kotlin Multiplatform (KMP) y expect/actual

\n

Para proyectos multiplataforma, Kotlin ofrece un potente mecanismo expect/actual que permite declarar una API común para i18n e implementarla por separado para cada plataforma.

\n\n
// En código común (commonMain)\nexpect class PlatformStringResources {\n    fun getString(key: String, vararg args: Any?): String\n}\n\n// En Android (androidMain)\nactual class PlatformStringResources {\n    private val context: Context = // obtenemos el contexto\n    \n    actual fun getString(key: String, vararg args: Any?): String {\n        val resId = context.resources.getIdentifier(key, "string", context.packageName)\n        return context.getString(resId, *args)\n    }\n}\n\n// En iOS (iosMain)\nactual class PlatformStringResources {\n    actual fun getString(key: String, vararg args: Any?): Str                    

Recommendations