Localize-Swift est une bibliothèque conçue pour simplifier la gestion multilingue et la commutation de langue à l'intérieur des applications iOS. Elle fournit une API concise qui s'intègre de manière idiomatique dans le code Swift.
Principes de fonctionnement fondamentaux
L'architecture repose sur l'extension des fonctionnalités natives de localisation et sur un système de notifications pour propager les changements de langue.
Persistance du choix de langue
La préférence de l'utilisateur concernant la langue de l'interface est stockée de manière persistante. La méthode pour récupérer la langue active vérifie d'abord cette préférence enregistrée.
func recupererLangueUtilisee() -> String {
guard let codeLangue = UserDefaults.standard.string(forKey: "langueSelectionnee") else {
return "en"
}
return codeLangue
}
Chargement dynamique des ressources
La traduction des chaînes de caractères s'effectue en chargeant le bundle de ressources correspondant à la langue active. Un mécanisme de repli garantit qu'une traduction est toujours disponible.
extension String {
func traduire(pourTable tableName: String? = nil) -> String {
let langue = recupererLangueUtilisee()
let mainBundle = Bundle.main
if let chemin = mainBundle.path(forResource: langue, ofType: "lproj"),
let bundleLangue = Bundle(path: chemin) {
return NSLocalizedString(self, tableName: tableName, bundle: bundleLangue, comment: "")
}
// Repli sur la langue de base du projet
return NSLocalizedString(self, tableName: tableName, comment: "")
}
}
Mise à jour de l'interface en temps réel
Pour que l'interface graphique reflète immédiatement un changement de langue, le système émet une notification. Les composants d'interface intéressés s'abonnent à cet événement pour déclencher une mise à jour.
// Emettre une notification après le changement
NotificationCenter.default.post(name: .langueModifiee, object: nil)
// Dans un contrôleur de vue pour réagir au changement
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(rechargerTextes), name: .langueModifiee, object: nil)
}
@objc func rechargerTextes() {
labelBienvenue.text = "Bonjour".traduire()
}
Organisation des fichiers de localisation
Les fichiers de ressources sont organisés dans des dossiers portant l'extension .lproj (comme fr.lproj, en.lproj), conformément aux conventions Apple. Chaque dossier contient un fichier Localizable.strings avec les paires clé-valeur pour les traductions.
Fonctionnalités avancées
La bibliothèque offre des commodités pour des cas courants :
- Formatage de chaînes : Insertion de variables dans les textes traduits.
- Gestion des pluriels : Sélection automatique de la bonne forme en fonction du nombre.
- Tableaux de strings personnalisés : Utilisation de fichiers
.stringsautres que celui par défaut.
// Formatage
let message = "Vous avez %d nouveaux messages".traduire()
let messageFinal = String(format: message, compteurMessages)
// Tableau personnalisé
let titre = "Confirmer".traduire(pourTable: "Boutons")
Considérations de performance
Le chargement des bundles de ressources est effectué à la demande et les instances sont mises en cache pour éviter des accès répétés au système de fichiers. Les mises à jour de l'interface sont assurées d'être exécutées sur le thread principal.
Comparaison avec l'approche standard
Par rapport à l'utilisation directe de NSLocalizedString, cette approche offre une syntaxe plus concise et un contrôle direct sur la langue de l'application, indépendamment des paramètres du système.
| Aspect | NSLocalizedString natif | Avec Localize-Swift |
|---|---|---|
| Syntaxe de base | NSLocalizedString("clé", comment: "") |
"clé".traduire() |
| Changement de langue | Dépend des paramètres système | Contrôlé dans l'application, immédiat |
Intégration dans un projet SwiftUI
Bien que principalement conçu pour UIKit, le mécanisme de notification et la fonction de traduction peuvent être intégrés dans une application SwiftUI. Un objet observable peut écouter la notification de changement de langue et provoquer une mise à jour de l'état des vues.
class EtatLangue: ObservableObject {
@Published var langueCourante: String = recupererLangueUtilisee()
init() {
NotificationCenter.default.addObserver(self, selector: #selector(langueModifiee), name: .langueModifiee, object: nil)
}
@objc func langueModifiee() {
langueCourante = recupererLangueUtilisee()
}
}
// Dans une Vue SwiftUI
struct VueTraduite: View {
@EnvironmentObject var etatLangue: EtatLangue
var body: some View {
Text("Bonjour".traduire())
.id(etatLangue.langueCourante) // Force la mise à jour
}
}
Cette architecture permet de construire des applications iOS flexibles et centrées sur l'utilisateur, capables de s'adapter à un public international sans nécessiter de redémarrage.