Guides 15 min de lecture
Localizable.strings sur iOS : format, exemples et migration vers les String Catalogs (2026)
Guide pratique du fichier Localizable.strings sur iOS : la syntaxe exacte "clé" = "valeur";, commentaires et échappements, dossiers .lproj et Base, recherche des chaînes avec NSLocalizedString, String(localized:) et Text, un .stringsdict minimal, erreurs fréquentes, plutil -lint et migration pas à pas vers les String Catalogs.
Sommaire14 parties
Localizable.strings est le fichier iOS classique qui contient les traductions d’une app : un fichier par langue, dans un dossier comme en.lproj ou fr.lproj, fait de lignes comme "Settings" = "Réglages";. Le code y cherche ses clés avec NSLocalizedString, String(localized:) ou le Text de SwiftUI, et par défaut, quand une clé manque, l’utilisateur voit la clé elle-même. Le format fonctionne toujours en 2026, mais Apple présente les catalogues de chaînes (String Catalogs, .xcstrings, Xcode 15 et ultérieur) comme son remplaçant, et Xcode sait migrer un fichier .strings en quelques clics. Ce guide détaille la syntaxe exacte, l’emplacement des fichiers, la recherche des traductions, les erreurs qui cassent un fichier, sa validation avec plutil -lint et la migration.
Points clés
- Chaque entrée s’écrit
"clé" = "valeur";, avec un point-virgule final ; guillemets et barres obliques inverses se protègent par une barre oblique inverse. - Une seule erreur de syntaxe peut rendre illisible toute la table d’une langue : chaque chaîne de cette langue affiche alors sa clé.
- Enregistrez les fichiers sources en UTF-8 ; Xcode les convertit dans l’app compilée (en UTF-16 par défaut).
- Passez
plutil -lintsur chaque fichier.stringsavant de compiler ou de migrer. - Pour tout nouveau travail, utilisez un catalogue de chaînes ; les fichiers existants se migrent table par table avec Migrate to String Catalog (Xcode 15 ou ultérieur).
Qu’est-ce que Localizable.strings ?
Un fichier de chaînes est une liste de paires clé-valeur : la clé est ce que demande le code, la valeur le texte affiché dans une langue. Le guide String Resources d’Apple (en anglais) nomme le fichier par défaut : « The name of the default strings file is Localizable.strings but you can create strings files with any file name you choose. » Chaque fichier forme une table, dont le nom est celui du fichier sans .strings : Localizable par défaut, Settings pour Settings.strings.
Les pluriels exigent un fichier .stringsdict complémentaire (voir plus bas) ; un catalogue de chaînes réunit les deux, pour toutes les langues, dans un seul fichier. Pour l’ensemble du processus, consultez notre guide de la localisation iOS.
Syntaxe : clés, valeurs, commentaires et échappements
Les règles d’Apple sont brèves : clé et valeur sont placées entre guillemets droits et séparées par un signe égal, l’entrée entière se termine par un point-virgule, et les commentaires s’écrivent entre délimiteurs de style C (/* et */), juste avant l’entrée qu’ils décrivent. Un fichier français complet ressemble à ceci :
/* fr.lproj/Localizable.strings */
/* Titre de l'onglet qui liste les éléments enregistrés */
"Saved" = "Enregistrés";
/* Clé explicite : le mot anglais peut changer sans casser les traductions */
"settings.title" = "Réglages";
/* %@ est le prénom de l'utilisateur */
"Welcome back, %@!" = "Bon retour, %@ !";
/* Les arguments positionnels permettent de réordonner les valeurs */
"%1$@ shared %2$lld photos" = "%2$lld photos partagées par %1$@";
/* Guillemets échappés et retour à la ligne */
"file.not.found" = "Le fichier \"%@\" est introuvable.\nVérifiez son nom.";| Pour écrire | Tapez | Exemple |
|---|---|---|
| Un guillemet dans une chaîne | \" | "Ouvrir \"%@\" ?" |
| Une barre oblique inverse | \\ | "C:\\Users" |
| Un retour à la ligne | \n | "Ligne 1\nLigne 2" |
| Un retour chariot | \r | Rarement utile sur les plateformes Apple |
| N’importe quel caractère Unicode | \U + jusqu’à quatre chiffres hexadécimaux | "\U202F" (espace fine insécable) |
| Un signe pour cent dans une chaîne de format | %% | "%lld %% terminé" |
La clé doit correspondre caractère pour caractère à ce que demande le code, spécificateurs de format compris. L’interpolation Swift d’un Int, comme dans String(localized: "\(count) photos"), produit la clé "%lld photos" et non "%d photos" ; un String produit %@. Apple accepte aussi des fichiers de chaînes au format liste de propriétés, mais le format entre guillemets ci-dessus reste l’usage.
Où vit le fichier : en.lproj, fr.lproj et Base.lproj
Une ressource localisée vit dans un dossier par langue, nommé d’après l’identifiant de langue avec l’extension .lproj : en.lproj, fr.lproj, pt-BR.lproj. Chaque dossier a son propre Localizable.strings, avec les mêmes clés et des valeurs traduites. À côté se trouvent parfois Localizable.stringsdict pour les pluriels et InfoPlist.strings pour les clés localisées d’Info.plist, comme le nom affiché et les textes d’autorisation.
Base.lproj est un cas à part : le guide d’internationalisation d’Apple en fait le dossier des storyboards et des XIB dans la langue de développement (« base internationalization »), pour lesquels des fichiers de chaînes sont générés par langue. Les chaînes utilisées dans le code vont dans Localizable.strings.
InfoPlist.strings : le nom de l’app et les demandes d’autorisation
InfoPlist.strings traduit les clés de Info.plist visibles par l’utilisateur, que Localizable.strings ne peut pas atteindre. Il utilise la même syntaxe "clé" = "valeur"; et vit dans les mêmes dossiers .lproj, mais ses clés sont les noms bruts des clés de Info.plist. La valeur écrite dans Info.plist reste la valeur de repli pour la langue de développement.
/* fr.lproj/InfoPlist.strings */
/* Nom sous l'icône sur l'écran d'accueil */
"CFBundleDisplayName" = "Mon Carnet";
/* Demande d'accès à l'appareil photo */
"NSCameraUsageDescription" = "L’appareil photo sert à scanner l’étiquette d’un produit.";- Nom de l’app :
CFBundleDisplayNameest le nom affiché sous l’icône. Le nom sur l’App Store est distinct et se règle langue par langue dans App Store Connect. - Demandes d’autorisation : chaque clé
NS…UsageDescription, comme l’appareil photo, le micro, la localisation ou Santé, affichée dans l’alerte système qui demande l’accès. - Le créer : ajoutez un fichier Strings nommé
InfoPlist, cliquez sur Localize dans l’inspecteur de fichier et cochez chaque langue. - Avec les String Catalogs :
InfoPlist.xcstringsle remplace, et Xcode y ajoute lui-même les clés localisables. Voir InfoPlist.xcstrings dans notre guide de localisation iOS.
Créer un fichier Localizable.strings
Pour un nouveau projet, créez plutôt un catalogue de chaînes (File › New › File from Template › String Catalog). S’il vous faut un fichier classique, par exemple pour rester cohérent avec un projet existant :
- Choisissez File › New › File from Template, tapez strings dans le champ de filtre et prenez le modèle de fichier de chaînes (pas String Catalog). Nommez-le
Localizablepour qu’il devienne la table par défaut. - Sélectionnez-le dans le navigateur de projet, ouvrez l’inspecteur de fichier et cliquez sur Localize, sous Localization, puis choisissez la langue de développement. L’article d’Apple sur les pluriels décrit les mêmes étapes pour un fichier
.stringsdict. - Cochez les autres langues dans le même panneau ; chacune ajoute une copie dans son dossier
.lproj. Les langues du projet sont listées dans l’éditeur de projet, onglet Info, rubrique Localizations. - Vérifiez que le fichier appartient à la bonne cible (Target Membership, dans l’inspecteur de fichier) : sinon, il n’arrive jamais dans l’app.
Comment iOS trouve une chaîne : NSLocalizedString, String(localized:) et Text
Chaque API prend une clé, une table et un bundle. La table par défaut est Localizable ; pour lire Settings.strings, passez "Settings".
// SwiftUI : un littéral est une LocalizedStringKey, cherchée dans Localizable.strings
Text("Saved")
Text("settings.title", tableName: "Settings")
// Swift hors des vues (iOS 15 et ultérieur)
let title = String(localized: "settings.title", table: "Settings",
comment: "Title of the Settings screen")
let toast = String(localized: "Welcome back, \(name)!") // clé : "Welcome back, %@!"
// Foundation, toute version d'iOS : value est renvoyée si la clé manque
let saved = NSLocalizedString("Saved", value: "Saved",
comment: "Tab title for the list of saved items")
// Dans un package Swift, cherchez les chaînes dans le bundle du package
Text("Saved", bundle: .module)| API | Paramètre de table | Si la clé est introuvable |
|---|---|---|
Text(_:tableName:bundle:comment:) | tableName | Affiche la clé |
String(localized:table:bundle:locale:comment:) | table | La clé sert aussi de valeur par défaut |
String(localized:defaultValue:table:…) | table | Renvoie defaultValue |
NSLocalizedString(_:tableName:bundle:value:comment:) | tableName | Renvoie value, ou la clé si value est vide |
Bundle.localizedString(forKey:value:table:) | table | Comme NSLocalizedString |
C’est le bundle qui choisit le dossier de langue : preferredLocalizations classe les localisations de l’app selon les préférences de l’utilisateur, et CFBundleDevelopmentRegion sert de langue quand le système ne trouve pas de ressource pour la langue préférée. Une clé absente n’est pas cherchée en anglais : la documentation de localizedString(forKey:value:table:) indique que la méthode renvoie la clé quand elle est introuvable et qu’aucune valeur n’est fournie. Des clés lisibles (« Saved ») se dégradent donc mieux que des clés techniques (« tab.saved »), sauf si vous passez une valeur par défaut.
Pluriels : un .stringsdict minimal
Un fichier .strings ne sait pas faire varier une phrase selon une quantité. Localizable.stringsdict, une liste de propriétés placée dans le même dossier .lproj, associe la clé de format à une chaîne par catégorie de pluriel. La plus petite version française utile :
<!-- fr.lproj/Localizable.stringsdict -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>%lld photos</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@photos@</string>
<key>photos</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>lld</string>
<key>one</key>
<string>%lld photo</string>
<key>other</key>
<string>%lld photos</string>
</dict>
</dict>
</dict>
</plist>// Swift : l'Int interpolé devient %lld, comme la clé du .stringsdict
Text("\(count) photos")
let label = String(localized: "\(count) photos")
// Foundation : formatez la chaîne trouvée avec le nombre
let format = NSLocalizedString("%lld photos", comment: "Number of photos in an album")
let text = String.localizedStringWithFormat(format, count)En français, la forme one couvre aussi zéro (« 0 photo »), selon les règles de pluriel Unicode CLDR ; le russe exige one, few, many et other. Les catalogues de chaînes remplacent toute cette liste de propriétés par Vary by Plural sur la clé, comme le détaille notre guide des pluriels dans les catalogues de chaînes.
Erreurs courantes et solutions
| Symptôme | Cause probable | Solution |
|---|---|---|
| Toutes les chaînes d’une langue affichent leur clé | Erreur de syntaxe quelque part dans le fichier de cette langue | Passer plutil -lint et corriger l’entrée en cause |
| Une chaîne affiche sa clé | Clé absente de la table, ou écrite autrement dans le code | Ajouter la clé ; comparer ponctuation et spécificateurs (%lld, %@) |
| Les caractères accentués cassent le fichier | Fichier enregistré dans un ancien encodage comme Latin-1 | Le réenregistrer en UTF-8 |
| Une traduction est fausse sans prévenir | Clé en double dans le même fichier | Repérer les doublons et n’en garder qu’un |
| Rien n’est jamais traduit | Fichier absent de la cible, mauvais nom de table ou mauvais bundle | Vérifier Target Membership, tableName et bundle |
Point-virgule manquant ou guillemet non échappé
La casse la plus fréquente : une ligne sans son ; final, un guillemet non échappé dans une valeur, ou des guillemets typographiques (“ ”) collés comme délimiteurs. Le fichier ne peut plus être lu, et toute la table est perdue pour cette langue. Lors de notre test avec un package Swift compilé par Xcode 27.2, un fichier français privé d’un seul point-virgule compilait sans avertissement, et à l’exécution chaque recherche en français renvoyait sa clé. plutil le détecte immédiatement :
$ plutil -lint fr.lproj/Localizable.strings
fr.lproj/Localizable.strings: (Unexpected character " at line 1)Ne vous fiez pas au numéro de ligne : dans nos tests, il indiquait « line 1 » pour une erreur à la ligne 4. Regardez plutôt la fin de chaque entrée, en commençant par les dernières modifiées.
Encodage : UTF-8 ou UTF-16 ?
Enregistrez le fichier que vous modifiez en UTF-8. Le réglage de compilation Strings File Output Encoding d’Apple indique que l’encodage de sortie est UTF-16 par défaut et que « It is recommended that the source file be in UTF-8 encoding » ; Xcode convertit le fichier à la compilation, et le traitement échoue si la conversion est impossible. L’UTF-16 est donc le format de la copie placée dans l’app compilée, pas un format à produire vous-même. Un fichier enregistré en Latin-1 avec des lettres accentuées échoue à plutil -lint avec le même message « Unexpected character ».
Clés en double
La règle d’Apple : « within a single strings file, each key must be unique ». genstrings signale les doublons, mais pas un fichier modifié à la main : plutil -lint répondait OK sur un fichier contenant deux fois la même clé, et dans notre test à l’exécution, c’est la seconde valeur qui l’emportait. Pour lister les doublons :
grep -o '^"[^"]*"' fr.lproj/Localizable.strings | sort | uniq -d« Localizable.strings ne fonctionne pas » : la clé s’affiche à la place de la traduction
- Passez chaque langue au lint, puis comparez la clé : elle doit correspondre exactement, ponctuation, espaces et spécificateurs de format compris.
- Vérifiez la table et le bundle. Un fichier nommé
Strings.stringsest la tableStrings; le code d’un framework ou d’un package doit chercher dans son propre bundle (.moduledans un package Swift), puisque le bundle principal est la valeur par défaut. - Vérifiez Target Membership et Localization dans l’inspecteur de fichier, et que la langue figure dans les Localizations du projet.
- Cherchez les variables de type String.
Text(label)avec une variableStrings’affiche telle quelle ; la documentation de Text proposeText(LocalizedStringKey(label))pour qu’elle soit cherchée. - Rendez les clés manquantes visibles. Avec le réglage utilisateur (user default)
NSShowNonLocalizedStringsréglé sur YES, Apple indique qu’une chaîne introuvable est consignée dans la console et sa clé mise en majuscules. Dans l’éditeur de schéma, Run › Options › « Show non-localized strings » aide à repérer le texte non traduit pendant le débogage.
Valider avec plutil -lint
Le guide String Resources d’Apple le recommande : « Running plutil with the -lint option can uncover hidden characters or other errors that are preventing strings from being retrieved correctly. » Lancez-le sur chaque fichier de chaînes, en local ou en intégration continue :
# Vérifier tous les fichiers .strings du dossier courant
find . -name "*.strings" -exec plutil -lint {} +
# Un fichier valide affiche :
# ./MyApp/fr.lproj/Localizable.strings: OK
# Compter les entrées d'une langue, pour comparer avec une autre
plutil -convert json -o - fr.lproj/Localizable.strings | python3 -c 'import json,sys; print(len(json.load(sys.stdin)))'plutil vérifie seulement que le fichier se lit : il ne signale ni les clés en double, ni les traductions manquantes, ni les placeholders incohérents.
Garder Localizable.strings ou migrer ?
Dans sa session Discover String Catalogs (WWDC23), Apple annonce que ce nouveau format remplacera à terme les fichiers strings et stringsdict, que les catalogues sont compilés en .strings et .stringsdict, sans changer la version minimale d’iOS, et qu’ils cohabitent avec les anciens formats. Xcode n’est pas non plus une raison d’attendre : depuis le 28 avril 2026, les builds envoyés sur l’App Store doivent être compilés avec Xcode 26 ou ultérieur (page Upcoming Requirements d’Apple).
| Votre situation | Recommandation |
|---|---|
| Nouvelle app ou nouvelle table | Catalogue de chaînes dès le départ |
| App existante en développement actif | Migrer d’abord Localizable, les autres tables ensuite |
| Gel de version ou grosse branche en cours | Garder les fichiers pour l’instant et migrer après la fusion, en un seul diff |
Un outil de traduction qui ne lit que les .strings | Vérifier s’il accepte les .xcstrings ou le XLIFF d’Export Localizations ; garder les fichiers en attendant |
| Pluriels ou textes par appareil tenus à la main | Migrer : Vary by Plural et Vary by Device remplacent le .stringsdict |
Migrer Localizable.strings vers un catalogue de chaînes, pas à pas
- Commencez par le lint. Passez
plutil -lintsur chaque langue et corrigez les erreurs, pour que toutes les traductions puissent être lues. Notez le nombre d’entrées par langue. - Faites un commit ou une branche, pour relire ou annuler la migration en un seul diff.
- Faites un clic droit (ou Contrôle-clic) sur
Localizable.stringsdans le navigateur de projet et choisissez Migrate to String Catalog, avec Xcode 15 ou ultérieur. - Choisissez les tables. Dans la démonstration d’Apple à la WWDC23, l’assistant de migration liste tous les fichiers migrables, par cible ; cochez
Localizable, et les autres tables quand vous serez prêt. - Laissez Xcode compiler. Il compile pour extraire les chaînes ; dans la démonstration d’Apple, toutes les chaînes du fichier strings, et même les pluriels du fichier stringsdict, arrivent dans
Localizable.xcstrings. - Comparez les nombres. Le nombre de clés du catalogue doit correspondre au nombre d’entrées de la langue source noté à l’étape 1 :
python3 -c 'import json; print(len(json.load(open("Localizable.xcstrings"))["strings"]))' - Faites le ménage. Ne laissez aucun fichier
.stringsou.stringsdictportant le même nom de table dans un dossier.lproj, puis lancez l’app dans chaque langue.
Votre code ne change pas, puisque la table s’appelle toujours Localizable. La checklist complète, avec le réglage de compilation à vérifier, se trouve dans la section Localizable.strings ou String Catalogs de notre guide de la localisation.
Après la migration : traduire le catalogue
Une fois vos chaînes dans un fichier .xcstrings, notre app Mac Xlocalize le traduit directement avec OpenAI, Anthropic Claude ou Google Gemini, avec votre propre clé d’API stockée dans le trousseau macOS. Elle préserve pluriels, variantes par appareil et substitutions, et signale les placeholders incohérents et les traductions manquantes. Elle travaille sur les catalogues de chaînes, pas sur les fichiers .strings : une raison de plus de migrer d’abord. Elle fonctionne sous macOS 14 ou ultérieur et se télécharge gratuitement, avec des achats intégrés facultatifs.
Pour confier tout le travail, de la migration à la relecture sur appareil et à la fiche App Store localisée, découvrez notre service de localisation d’application.
Questions fréquentes
Qu’est-ce que le fichier Localizable.strings ?
Le fichier de chaînes par défaut d’une app iOS ou macOS : des entrées "clé" = "valeur";, une copie par langue dans des dossiers comme en.lproj et fr.lproj. NSLocalizedString, String(localized:) et Text lisent sa table, Localizable, sauf si vous en indiquez une autre.
Comment créer un fichier Localizable.strings dans Xcode ?
Choisissez File › New › File from Template, filtrez sur strings, prenez le modèle de fichier de chaînes et nommez-le Localizable. Cliquez ensuite sur Localize dans l’inspecteur de fichier et cochez chaque langue. Pour un nouveau projet, créez plutôt un catalogue de chaînes (Localizable.xcstrings), que Xcode remplit à chaque compilation.
Pourquoi mon Localizable.strings ne fonctionne-t-il pas ?
Si toutes les chaînes d’une langue affichent leur clé, le fichier ne se lit pas : passez plutil -lint et cherchez un point-virgule manquant ou un guillemet non échappé. Sinon, vérifiez que la clé correspond exactement, que le fichier est dans la cible, ainsi que le nom de table, le bundle et toute variable String passée à Text, comme dans la liste ci-dessus.
Localizable.strings est-il obsolète ?
Pas officiellement : il fonctionne toujours, et les catalogues de chaînes deviennent eux-mêmes des fichiers .strings et .stringsdict à la compilation. Mais Apple présente les catalogues comme la méthode recommandée pour localiser les pluriels avec Xcode 15 et ultérieur, et a annoncé à la WWDC23 que le nouveau format remplacera à terme les fichiers strings et stringsdict.
Localizable.strings ou Localizable.xcstrings : lequel choisir ?
Localizable.xcstrings pour tout nouveau travail : un seul fichier pour toutes les langues, pluriels compris, synchronisé avec votre code à chaque compilation. Gardez Localizable.strings seulement tant que votre processus en dépend, puis utilisez Migrate to String Catalog.
Qu’est-ce que le fichier InfoPlist.strings ?
C’est le fichier de chaînes qui traduit les valeurs de Info.plist : le nom de l’app sous l’icône (CFBundleDisplayName) et les demandes d’autorisation (NSCameraUsageDescription et les autres clés NS…UsageDescription). Chaque langue a sa copie dans son dossier .lproj, avec les noms des clés de Info.plist comme clés. Dans un projet à String Catalogs, InfoPlist.xcstrings joue le même rôle. Voir InfoPlist.strings.
Un projet d’app iOS ?
Swift et SwiftUI natifs, du premier croquis à l’App Store, et au-delà.
Démarrer un projetSommaire