Skip to main content

Guida completa alla localizzazione delle applicazioni iOS

Da Localizable.strings ai metadati App Store: localizzare un'app iOS con Xcode, SwiftUI, Fastlane e traduzione IA automatizzata.

1

Abilitare la localizzazione in Xcode

Aprire le impostazioni del progetto Xcode, selezionare Info > Localizations e aggiungere le lingue da supportare. Xcode crea automaticamente una directory .lproj per ogni lingua.

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 localizzazione Base separa l'interfaccia dalle stringhe. Quando aggiunge una lingua, Xcode propone di creare versioni localizzate di storyboard, XIB e file di stringhe.
2

Creare Localizable.strings

Il file di localizzazione iOS standard usa coppie chiave-valore separate dal segno uguale e ogni riga termina con un punto e virgola. Inserirlo nella cartella Base.lproj della lingua sorgente.

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
L'assenza dei punti e virgola causa errori senza segnalazioni: il file viene caricato, ma le traduzioni sono vuote. Assicurarsi inoltre che sia incluso nella fase Copy Bundle Resources del target, altrimenti non entrerà nel bundle dell'applicazione.
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

Migrare agli String Catalog (Xcode 15+)

Gli String Catalog (.xcstrings) sono la moderna alternativa Apple ai file .strings. Offrono un editor visivo in Xcode, estrazione automatica dalle viste SwiftUI e supporto integrato dei plurali.

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")
Gli String Catalog memorizzano TUTTE le lingue in un solo file JSON .xcstrings. Nei team questo causa frequenti conflitti Git quando più persone aggiungono stringhe. Nei progetti grandi, considerare un catalogo per modulo.
4

Usare stringhe localizzate in SwiftUI e UIKit

La vista Text di SwiftUI localizza automaticamente le stringhe letterali. UIKit usa NSLocalizedString. Da iOS 16, la moderna API String(localized:comment:) offre una sintassi più pulita e supporto del compilatore.

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)") non viene localizzato senza segnalazioni se name è una normale variabile String. L'interpolazione SwiftUI crea un LocalizedStringKey, ma soltanto tipi specifici (Int, Double e così via) vengono interpolati correttamente. Per String, creare prima la stringa con String(localized:).
5

Gestire i plurali

iOS usa file .stringsdict per le regole plurali e supporta tutte le categorie CLDR: zero, one, two, few, many, other. Gli String Catalog le gestiscono con un editor visivo, molto più semplice della scrittura manuale di XML 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)
L'arabo ha 6 forme plurali, il russo 3 e il giapponese 1. Definire sempre tutte le categorie CLDR necessarie. L'editor visivo degli String Catalog semplifica il compito.
6

Localizzare i metadati App Store con Fastlane

Usare deliver di Fastlane per conservare nel repository i metadati App Store, tra cui nome, sottotitolo, descrizione, parole chiave e note di rilascio, come file di testo organizzati per lingua e soggetti a controllo di versione.

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
Localizzazione incrociata: App Store USA indicizza parole chiave inglesi e spagnole. Localizzare i metadati in spagnolo intercetta le ricerche degli utenti ispanici negli Stati Uniti senza scegliere un mercato separato.
7

Testare la localizzazione

Testare i contenuti senza cambiare la lingua del dispositivo: usare le sostituzioni dello schema Xcode, le anteprime SwiftUI con ambiente locale e XCUITest con argomenti di avvio per i test automatizzati.

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()
Testare con tedesco, le cui stringhe si espandono di circa il 30%, e giapponese, che si riduce di circa il 50%, per individuare presto problemi di layout. Usare la pseudolocalizzazione Xcode per prove di stress senza traduzioni reali.

Automatizzare la qualità

Rilevare chiavi mancanti, segnaposto danneggiati e problemi di plurali con i18n-validate. Testare l'interfaccia con pseudotraduzioni tramite i18n-pseudo prima che arrivino quelle reali.
8

Automatizzare le traduzioni

Tradurre file .strings, .xcstrings e metadati Fastlane con l'IA. Automatizzare sia le stringhe dell'applicazione sia i metadati App Store per una presenza completamente localizzata.

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 presenza App Store localizzata aumenta i download di oltre il 30% nei mercati non anglofoni. Tradurre i metadati insieme alle stringhe dell'applicazione offre il massimo ritorno sull'investimento.
+

Extra: fallback intelligente con LocaleChain

Per impostazione predefinita, iOS usa la lingua di sviluppo quando la lingua esatta dell'utente non è disponibile. Un utente pt-BR con sole traduzioni pt-PT vede l'inglese. LocaleChain risolve il problema con catene configurabili.

LocaleChain è un pacchetto Swift open source. Visualizzare su 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"]]
)

Problemi comuni

Errori di sintassi nei file .strings

Punti e virgola mancanti, virgolette senza escape o codifica errata causano errori senza segnalazioni. Il file si carica, ma le traduzioni sono vuote. Validare sempre i file .strings prima del commit.

L'interpolazione Text di SwiftUI non viene localizzata

Text("Hello \(stringVar)") non viene localizzato come previsto. Usare String(localized:) per le stringhe calcolate o verificare che le variabili abbiano un tipo supportato da LocalizedStringKey.StringInterpolation.

Widget/estensioni mostrano chiavi grezze

Le estensioni hanno bundle separati. Assicurarsi che i file .strings o .xcstrings siano aggiunti alla fase Copy Bundle Resources del target dell'estensione e non soltanto a quello principale.

Le traduzioni mancanti mostrano le chiavi in produzione

Se una chiave non ha una traduzione nella lingua dell'utente, iOS mostra la chiave stessa. Usare una strategia di fallback e testare tutte le lingue supportate prima del rilascio.

Struttura dei file consigliata

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

Provi subito i18n Agent

Trascinare qui il file di traduzione

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

oppure fare clic per selezionarlo

Lingue di destinazione

Nessuna registrazione richiestaPreventivo immediato

Fallback della lingua con ios-localechain

Quando manca una chiave in una variante regionale come de-AT, iOS passa direttamente alla lingua di sviluppo anziché verificare prima 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"],
])

Consultare la Guida al fallback delle lingue per l'elenco completo dei framework supportati e delle 75 catene integrate. Learn more →

Domande frequenti sulla localizzazione iOS