Skip to main content

Guía completa para localizar aplicaciones iOS

Desde Localizable.strings hasta los metadatos de App Store: localice su aplicación iOS con Xcode, SwiftUI, Fastlane y traducción automatizada mediante IA.

1

Activar la localización en Xcode

Abra los ajustes de su proyecto de Xcode, vaya a Info > Localizations y añada los idiomas que quiera admitir. Xcode crea automáticamente directorios .lproj para cada idioma.

Xcode Project Settings
// In Xcode:
// 1. Select your project in the navigator
// 2. Go to Info tab > Localizations
// 3. Click + to add languages (e.g., German, Japanese)
// 4. Select which files to localize
//
// Xcode creates .lproj directories automatically:
// en.lproj/Localizable.strings
// de.lproj/Localizable.strings
// ja.lproj/Localizable.strings
La localización base separa la interfaz de sus cadenas. Cuando añade un idioma, Xcode le ofrece crear versiones localizadas de los storyboards, XIB y archivos de cadenas.
2

Crear Localizable.strings

El archivo estándar de localización de iOS utiliza pares de clave y valor separados por signos igual, y cada línea termina con punto y coma. Colóquelo en la carpeta Base.lproj del idioma de origen.

Base.lproj/Localizable.strings
// Base.lproj/Localizable.strings

"welcome_title" = "Welcome to MyApp";
"login_button" = "Sign In";
"settings_label" = "Settings";
"greeting" = "Hello, %@!";    // %@ = string placeholder
"item_count" = "%d items";     // %d = integer placeholder
La ausencia de punto y coma provoca fallos silenciosos: el archivo se carga sin errores, pero las traducciones quedan vacías. Asegúrese también de añadir el archivo a la fase de compilación Copy Bundle Resources del destino; de lo contrario, no se incluirá en el paquete de la aplicación.
Common .strings Mistakes
// ❌ Common mistakes in .strings files:

// Missing semicolon — file loads but translations are empty
"welcome_title" = "Welcome"

// Unescaped quotes — causes parse error
"message" = "Click "here" to continue";

// ✅ Correct versions:
"welcome_title" = "Welcome";
"message" = "Click \"here\" to continue";
3

Migrar a catálogos de cadenas (Xcode 15 o posterior)

Los catálogos de cadenas (.xcstrings) son el sustituto moderno de Apple para los archivos .strings. Ofrecen un editor visual en Xcode, extracción automática de cadenas desde sus vistas de SwiftUI y compatibilidad integrada con plurales.

Localizable.xcstrings
// Xcode 15+ String Catalog (Localizable.xcstrings)
// Xcode automatically extracts strings from your code
// and manages translations in a visual editor.

// In SwiftUI, strings are automatically localizable:
Text("Welcome to MyApp")
Text("Hello, \(userName)!")

// Mark strings explicitly:
let title = String(localized: "welcome_title")
Los catálogos de cadenas almacenan TODOS los idiomas en un único archivo JSON .xcstrings. En los equipos, esto genera conflictos frecuentes de fusión en Git cuando varias personas añaden cadenas. En proyectos grandes, considere utilizar un catálogo por módulo.
4

Utilizar cadenas localizadas en SwiftUI y UIKit

La vista Text de SwiftUI localiza automáticamente los literales de cadena. UIKit utiliza NSLocalizedString. A partir de iOS 16, la moderna API String(localized:comment:) ofrece una sintaxis más clara con compatibilidad integrada en el compilador.

ContentView.swift
import SwiftUI

struct ContentView: View {
    let userName: String

    var body: some View {
        VStack {
            // ✅ SwiftUI auto-localizes string literals
            Text("welcome_title")

            // ⚠️ This does NOT localize (String interpolation)
            // Text("Hello, \(userName)")

            // ✅ Use String(localized:) for dynamic strings
            Text(String(localized: "greeting \(userName)"))

            // ✅ UIKit style (works everywhere)
            let title = NSLocalizedString(
                "settings_label",
                comment: "Settings screen title"
            )

            // ✅ Modern API (iOS 16+)
            let modern = String(
                localized: "welcome_title",
                comment: "Main screen title"
            )
        }
    }
}
Text("Hello \(name)") no se localiza silenciosamente cuando name es una variable String normal. La interpolación de cadenas de SwiftUI crea una LocalizedStringKey, pero solo interpola correctamente determinados tipos (Int, Double, etc.). Para variables String, utilice primero String(localized:) para crear la cadena localizada.
5

Gestionar plurales

iOS utiliza archivos .stringsdict para las reglas de plural y admite todas las categorías CLDR: zero, one, two, few, many y other. Los catálogos de cadenas gestionan los plurales mediante un editor visual en Xcode, mucho más sencillo que escribir a mano XML de stringsdict.

Localizable.stringsdict
<!-- Localizable.stringsdict -->
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
    <key>items_count</key>
    <dict>
        <key>NSStringLocalizedFormatKey</key>
        <string>%#@count@</string>
        <key>count</key>
        <dict>
            <key>NSStringFormatSpecTypeKey</key>
            <string>NSStringPluralRuleType</string>
            <key>NSStringFormatValueTypeKey</key>
            <string>d</string>
            <key>zero</key>
            <string>No items</string>
            <key>one</key>
            <string>%d item</string>
            <key>other</key>
            <string>%d items</string>
        </dict>
    </dict>
</dict>
</plist>

// Usage in Swift:
String(format: NSLocalizedString("items_count", comment: ""),
       itemCount)
Idiomas como el árabe tienen 6 formas plurales, el ruso 3 y el japonés 1. Defina siempre todas las categorías CLDR que necesiten sus idiomas de destino. Los catálogos de cadenas lo facilitan mediante su editor visual de plurales.
6

Localizar los metadatos de App Store con Fastlane

Utilice la herramienta deliver de Fastlane para conservar bajo control de versiones los metadatos de App Store —nombre, subtítulo, descripción, palabras clave y notas de la versión— como archivos de texto sin formato organizados por configuración regional.

Terminal
# Install Fastlane
$ gem install fastlane

# Initialize deliver for App Store metadata
$ fastlane deliver init

# Directory structure created:
# fastlane/metadata/
# ├── en-US/
# │   ├── name.txt            # App name (30 chars)
# │   ├── subtitle.txt        # Subtitle (30 chars)
# │   ├── description.txt     # Full description
# │   ├── keywords.txt        # Search keywords (100 chars)
# │   ├── release_notes.txt   # What's New
# │   └── promotional_text.txt
# ├── de-DE/
# │   └── ...
# └── ja/
#     └── ...

# Push metadata to App Store Connect:
$ fastlane deliver
Localización cruzada: la App Store de Estados Unidos indexa palabras clave tanto en inglés como en español. Localizar sus metadatos al español capta las búsquedas de los usuarios hispanos de Estados Unidos sin dirigirse a otro mercado.
7

Probar su localización

Pruebe el contenido localizado sin cambiar el idioma del dispositivo. Utilice las anulaciones de esquemas de Xcode para ejecutar la aplicación en cualquier idioma, vistas previas de SwiftUI con un entorno de configuración regional y XCUITest con argumentos de inicio para automatizar las pruebas.

Testing Localization
// 1. Xcode Scheme Override:
// Edit Scheme > Run > Options > App Language > Choose language

// 2. SwiftUI Preview with locale:
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .environment(\.locale, Locale(identifier: "de"))

        ContentView()
            .environment(\.locale, Locale(identifier: "ja"))

        ContentView()
            .environment(\.locale, Locale(identifier: "ar"))
    }
}

// 3. XCUITest with language override:
let app = XCUIApplication()
app.launchArguments += ["-AppleLanguages", "(de)"]
app.launchArguments += ["-AppleLocale", "de_DE"]
app.launch()
Pruebe con alemán —las cadenas se alargan alrededor de un 30 % respecto al inglés— y japonés —se acortan aproximadamente un 50 %— para detectar pronto problemas de diseño. Utilice la pseudolocalización de Xcode para someter los diseños a pruebas exigentes sin traducciones reales.

Automatizar la calidad de la traducción

Detecte las claves ausentes, los marcadores de posición rotos y los problemas de plurales antes de publicar con i18n-validate. Pruebe la interfaz con pseudotraducciones mediante i18n-pseudo antes de recibir las reales.
8

Automatizar traducciones

Traduzca sus archivos .strings, .xcstrings y de metadatos de Fastlane con IA. Automatice tanto las cadenas de la aplicación como los metadatos de App Store para ofrecer una presencia completamente localizada.

Terminal
# Translate .strings files
> Translate Base.lproj/Localizable.strings
  to Japanese, German, and Spanish

# Translate App Store metadata too
> Translate fastlane/metadata/en-US/
  to de-DE, ja, es-MX

✓ 6 files translated in 3.2s
Una presencia localizada en App Store aumenta las descargas más de un 30 % en mercados donde no se habla inglés. Traduzca los metadatos junto con las cadenas de la aplicación: es la localización con mayor retorno de la inversión que puede realizar.
+

Extra: respaldo inteligente de configuraciones regionales con LocaleChain

De forma predeterminada, iOS recurre al idioma de desarrollo cuando no está disponible la configuración regional exacta del usuario. Un usuario pt-BR que solo dispone de traducciones pt-PT ve inglés en lugar de portugués. LocaleChain lo corrige con cadenas de respaldo configurables.

LocaleChain es un paquete Swift de código abierto. Ver en GitHub

Package Dependencies
// Swift Package Manager
// File > Add Package Dependencies >
// https://github.com/i18n-agent/ios-localechain.git
MyApp.swift
import LocaleChain

// In your App init or AppDelegate:
LocaleChain.configure()  // Activates all default chains

// pt-BR user with only pt-PT translations?
// → Shows Portuguese instead of falling back to English

// Custom overrides for your specific locales:
LocaleChain.configure(
    overrides: ["es-MX": ["es-419", "es"]]
)

Errores habituales

Errores de sintaxis en archivos .strings

La ausencia de puntos y coma, las comillas sin escapar o una codificación incorrecta provocan fallos silenciosos. El archivo se carga, pero las traducciones aparecen vacías. Valide siempre los archivos .strings antes de confirmar los cambios.

La interpolación de Text en SwiftUI no se localiza

Text("Hello \(stringVar)") no se localiza como se espera. Utilice String(localized:) para cadenas calculadas o asegúrese de que las variables interpoladas tengan el tipo correcto para LocalizedStringKey.StringInterpolation.

Los widgets y las extensiones muestran claves sin procesar

Las extensiones de aplicaciones tienen paquetes independientes. Asegúrese de añadir los archivos .strings o .xcstrings a la fase Copy Bundle Resources del destino de la extensión, no solo al destino de la aplicación principal.

Las traducciones ausentes muestran claves en producción

Cuando una clave no tiene traducción en el idioma del usuario, iOS muestra la propia clave. Utilice una estrategia de idioma de respaldo y pruebe todas las configuraciones regionales admitidas antes de publicar.

Estructura de archivos recomendada

Project Structure
MyApp/
├── MyApp.xcodeproj
├── MyApp/
│   ├── Base.lproj/
│   │   ├── Localizable.strings       # Source strings
│   │   └── Localizable.stringsdict   # Plural rules
│   ├── en.lproj/
│   │   └── Localizable.strings
│   ├── de.lproj/
│   │   └── Localizable.strings
│   ├── ja.lproj/
│   │   └── Localizable.strings
│   ├── Localizable.xcstrings          # OR String Catalog
│   └── Info.plist
├── MyAppTests/
├── fastlane/
│   ├── Fastfile
│   └── metadata/
│       ├── en-US/
│       │   ├── name.txt
│       │   ├── description.txt
│       │   └── keywords.txt
│       ├── de-DE/
│       └── ja/
└── Package.swift

Pruebe i18n Agent ahora

Arrastre y suelte aquí su archivo de traducción

JSON, YAML, PO, XML, CSV, Markdown, Properties

o haga clic para seleccionar

Idiomas de destino

No es necesario registrarsePresupuesto al instante

Respaldo de configuraciones regionales con ios-localechain

Cuando falta una clave de traducción en una configuración regional como de-AT, iOS pasa directamente al idioma de desarrollo en vez de comprobar primero la configuración principal de.

Terminal
// Swift Package Manager
// https://github.com/i18n-agent/ios-localechain
Configuration
import LocaleChain

LocaleChain.configure(overrides: [
    "de": ["en-GB", "en"],
    "pt-BR": ["pt", "en"],
    "zh-Hant-HK": ["zh-Hant", "zh", "en"],
])

Consulte nuestra guía de respaldo de configuraciones regionales para ver todos los frameworks admitidos y las 75 cadenas integradas. Learn more →

Preguntas frecuentes sobre localización de iOS