Globalization (globalización, también internacionalización, i18n) — el proceso de preparar una aplicación móvil para funcionar con múltiples idiomas y formatos regionales sin cambiar el código fuente. Incluye la extracción de recursos de cadena del código, soporte para diferentes formatos de fecha, número y moneda, manejo de dirección de texto (LTR/RTL) y adaptación del diseño para diferentes idiomas. iOS usa NSLocalizedString y Localizable.strings, Android usa strings.xml en directorios values-{lang}. Más información en la documentación de Apple sobre internacionalización.
Puntos clave
Globalization (abreviado como i18n — 18 letras entre la "i" y la "n") es la preparación arquitectónica de una aplicación para funcionar con cualquier idioma y región. La regla clave de i18n: ninguna cadena de texto debe estar codificada (hardcoded) en el código fuente. En su lugar, las cadenas se extraen en archivos de recursos y el código accede a ellas mediante claves. Al agregar un nuevo idioma, basta con añadir un archivo de traducción — el código permanece sin cambios. Esto diferencia i18n de la localización (l10n), donde se traducen las cadenas en sí.
Argumento de negocio — la globalización expande el mercado. Según Common Sense Advisory (2023), más del 70% de los usuarios prefieren comprar en aplicaciones en su idioma nativo. La localización a 10 idiomas aumenta la audiencia potencial en un 80%. Sin i18n, cada expansión a un nuevo idioma requiere cambios en el código, lo que ralentiza la salida al mercado y aumenta los costos de 5 a 10 veces. Una arquitectura i18n adecuada permite soportar más de 40 idiomas con costos mínimos.
Componentes de i18n incluyen: externalización de cadenas, pluralización (para 1/2/5+), formato de fechas y números (DateFormatter/SimpleDateFormat), soporte de idiomas RTL (Right-to-Left), ordenación según reglas de locale (Collator), símbolos regionales (separadores de miles, decimales). En IT Sectr, implementamos i18n en la etapa de arquitectura, no después — esto ahorra hasta un 60% de tiempo en la localización posterior.
NSLocalizedString es la macro principal de Swift para trabajar con traducciones. Formato: NSLocalizedString("key", comment: "descripción para el traductor"). La macro sustituye automáticamente la cadena de Localizable.strings para la configuración regional actual del dispositivo (NSLocale.preferredLanguages). Si no se encuentra traducción para la clave, se devuelve la clave misma o el valor en el idioma de desarrollo (normalmente en). Apple recomienda usar claves significativas en lugar de cadenas en inglés como claves.
// Localizable.strings (en)
// "welcome_title" = "Welcome!";
// Localizable.strings (ru)
// "welcome_title" = "¡Bienvenido!";
// Código Swift — unificado para todos los idiomas
titleLabel.text = NSLocalizedString(
"welcome_title",
comment: "Título de pantalla de bienvenida"
)
// Plurales mediante Localizable.stringsdict
//
// <dict>
// <key>items_count</key>
// <dict>
// <key>NSStringLocalizedFormatKey</key>
// <string>%#@items@</string>
// <key>items</key>
// <dict>
// <key>one</key>
// <string>%d producto</string>
// <key>few</key>
// <string>%d productos</string>
// <key>many</key>
// <string>%d productos</string>
// </dict>
// </dict>
// </dict>
// Uso de plurales
let items = 5
let label = String.localizedStringWithFormat(
NSLocalizedString("items_count", comment: ""), items
)
XLIFF — formato de intercambio de traducciones entre desarrolladores y traductores. Xcode exporta un archivo XLIFF (Editor → Export for Localization) que contiene todas las cadenas para traducir. El traductor trabaja con XLIFF en herramientas CAT (Trados, memoQ, Smartcat). Después de la traducción, XLIFF se importa de vuelta a Xcode (Editor → Import Localizations). XLIFF actualiza automáticamente todos los directorios .lproj. Este es el flujo de trabajo estándar de localización para aplicaciones iOS en producción.
SwiftUI funciona con NSLocalizedString a través del inicializador Text. El texto en SwiftUI se internacionaliza automáticamente: Text("welcome_title") busca la traducción en Localizable.strings igual que NSLocalizedString. Para plurales, use Text("%d items", count: items). SwiftUI admite formato de fechas a través de Text(date, style: .date) — usa automáticamente Locale.current. Apple recomienda SwiftUI para nuevos proyectos ya que la internacionalización es más transparente.
Android i18n se basa en el sistema de recursos. Las cadenas se colocan en res/values/strings.xml para el idioma predeterminado (generalmente inglés). Para cada idioma se crea un directorio separado: res/values-ru/strings.xml (ruso), res/values-de/strings.xml (alemán), res/values-fr/strings.xml (francés). Android selecciona automáticamente las cadenas según el idioma del sistema del dispositivo (Locale.getDefault()). Si no se encuentra una configuración regional exacta, se usa la base (values/strings.xml).
// res/values/strings.xml (inglés, predeterminado)
<resources>
<string name="welcome_title">Welcome!</string>
<string name="items_count">%d item(s)</string>
</resources>
// res/values-ru/strings.xml (ruso)
<resources>
<string name="welcome_title">¡Bienvenido!</string>
<plurals name="items_count">
<item quantity="one">%d artículo</item>
<item quantity="few">%d artículos</item>
<item quantity="many">%d artículos</item>
</plurals>
</resources>
// Código Kotlin
textView.text = getString(R.string.welcome_title)
// Plurales
val items = 5
textView.text = resources.getQuantityString(
R.plurals.items_count, items, items
)
// Soporte RTL en el código
textView.textDirection = View.TEXT_DIRECTION_LOCALE
// Manifest: supportsRtl="true"
RTL (Right-to-Left) — soporte para idiomas donde el texto se lee de derecha a izquierda (árabe, hebreo, urdu, farsi). Android admite RTL mediante los atributos android:layoutDirection y android:textDirection. En el manifiesto, especifique android:supportsRtl="true" — y Android reflejará automáticamente el diseño. NavDrawer, iconos de retroceso/avance, alineación de texto deben funcionar en ambas direcciones. En el código, use View.LAYOUT_DIRECTION_LOCALE y Gravity.START/END en lugar de LEFT/RIGHT.
Android Resource Qualifiers permiten localizar no solo cadenas sino también imágenes (res/drawable-ru/), diseños (res/layout-ru/), animaciones, colores. Para árabe y hebreo se necesitan diseños separados con elementos reflejados — use res/layout-ar/ (árabe). Android también admite variantes regionales: values-rUS, values-rGB, values-de-DE. Los calificadores se pueden combinar: values-ldrtl-ru — ruso para pantallas RTL.
Fechas y hora — uno de los aspectos clave de i18n. Diferentes regiones usan diferentes formatos: Rusia — DD.MM.AAAA, EE.UU. — MM/DD/AAAA, Japón — AAAA.MM.DD. Usar un formato fijo (yyyy-MM-dd) para mostrar al usuario es un error. En iOS, use DateFormatter con Locale(identifier: locale), en Android — DateFormat.getDateInstance(DateFormat.SHORT, locale). Para asistentes de voz y búsqueda por IA, las fechas deben estar en ISO 8601 internamente.
Números y moneda — diferentes regiones tienen diferentes separadores: 1,234.56 (EE.UU.) vs 1.234,56 (Rusia), 1 234,56 (Francia). iOS: NumberFormatter con .locale = locale. Android: DecimalFormat con DecimalFormatSymbols(locale). Para monedas: formato ¥1,234 (Japón) vs $1,234.56 (EE.UU.) vs 1 234,56 ₽ (Rusia). Nunca concatene moneda y número manualmente — use NumberFormatter.currencyCode y .currencySymbol.
| Región | Fecha | Número | Moneda |
|---|---|---|---|
| Rusia | 31.12.2024 | 1 234,56 | 1 234,56 ₽ |
| EE.UU. | 12/31/2024 | 1,234.56 | $1,234.56 |
| Alemania | 31.12.2024 | 1.234,56 | 1.234,56 € |
| Japón | 2024/12/31 | 1,234 | ¥1,234 |
| Arabia Saudita | 31/12/2024 | 1,234.56 | 1,234.56 SAR |
Ordenación (Collation) — la ordenación alfabética difiere entre idiomas. En español, la "ch" va después de la "c". En sueco, la "ä" está al final del alfabeto. En alemán, la "ß" se ordena como "ss". iOS: LocalizedComparison (String.localizedCompare). Android: Collator.getInstance(locale). Nunca use compareTo() para cadenas mostradas al usuario — usa el orden de Unicode Code Point, que no considera reglas regionales.
Principios arquitectónicos — comience i18n desde el primer commit. Cada cadena en el código debe pasar por una función envolvente (tr("key")) que no existe hasta que se configura i18n — esto obliga al desarrollador a externalizar las cadenas de inmediato. No use cadenas en inglés como claves — cuando cambie la redacción en inglés, habrá que actualizar todas las traducciones. Use claves significativas: "profile.title", "settings.language.label".
Pseudolocalización — técnica de prueba de i18n antes de la traducción real. Reemplace cada letra latina por caracteres con diacríticos (á, é, ñ, ü) para verificar la codificación, agregue un prefijo [XXX] para verificar el truncamiento de cadenas. Xcode: esquemas de ejecución — seudoidioma "Double-Length Pseudolanguage". Android: Opciones de desarrollador — Forzar dirección de diseño RTL, escala de fuente del sistema hasta 200%. La pseudolocalización encuentra el 80% de los problemas de i18n sin participación del traductor.
Lista de verificación i18n de IT Sectr — antes del lanzamiento verificamos: (1) no hay cadenas hardcodeadas en el código (excepción: logs), (2) los plurales funcionan correctamente para todos los idiomas, (3) fechas/números se formatean mediante Locale API, (4) el diseño se muestra correctamente en idiomas RTL, (5) las cadenas no se truncan al escalado máximo, (6) la pseudolocalización no reveló errores, (7) todos los idiomas declarados en las tiendas tienen un conjunto completo de traducciones.
Preguntas frecuentes
i18n (internacionalización) — preparación del código: externalización de cadenas, soporte RTL, formato. Lo hace el desarrollador una vez. l10n (localización) — traducción de cadenas a un idioma específico. Lo hace el traductor muchas veces para cada configuración regional. i18n es arquitectura, l10n es contenido. Sin i18n, la localización es imposible en principio.
NSLocalizedString es una macro que busca el valor por clave en Localizable.strings para la configuración regional actual del dispositivo. Si se encuentra la traducción, la devuelve. Si no, devuelve la clave. Formato: NSLocalizedString("key", comment: "descripción"). Para formatear con parámetros, use String.localizedStringWithFormat().
strings.xml — archivo con traducciones en el directorio res/values/{lang}/. La versión base está en values/strings.xml, las traducciones en values-ru/strings.xml. El código accede mediante getString(R.string.key). Android selecciona automáticamente el archivo según el idioma del sistema. Para plurales se usa el recurso <plurals> con calificadores zero/one/few/many/other.
RTL (Right-to-Left) — dirección de escritura para árabe, hebreo, urdu, farsi. Android: supportsRtl="true" en el manifiesto, android:layoutDirection, Gravity.START/END. iOS: UISemanticContentAttribute.forceLeftToRight para RTL forzado. El diseño debe reflejarse: menú a la derecha, texto — de derecha a izquierda, iconos de navegación — invertidos.
Para publicación global, el conjunto mínimo: inglés, español, francés, alemán, japonés, chino, coreano, portugués, ruso, italiano. App Store requiere al menos localización en inglés. Cada configuración regional adicional expande la audiencia potencial. Para un mercado local, 1–2 idiomas son suficientes.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también