Upload
cocoaheadsrns
View
1.744
Download
2
Embed Size (px)
DESCRIPTION
Slides de la présentation "Traduction automatique et intelligente d'applications Cocoa" de la session des CocoaHeads Rennais du 21 avril 2011. Présentation assurée par Olivier Halligon, créateur de Food Reporter.
Citation preview
Traduction des interfaces de vos applications Cocoa
Olivier Halligon, avril 2011
Som
mai
re
Sommaire
• Introduction
• Traduction par la méthode «standard»
• La traduction automatiquede votre interface
• Astuces, pièges à éviter
• Conclusion
2
Intr
oduc
tion
Introduction
• Présentation
• Olivier Halligon
• Food Reporter
• Objectif
• Base de la traduction
• Traduction auto de XIB
3
Food Reporter
Trad
uctio
n pa
r la
mét
hode
«st
anda
rd»
Traduction par la méthode «standard»
• Ressources localisées
• Fichiers «strings»
• Limitations de cette méthode
4
Trad
uctio
n pa
r la
mét
hode
«st
anda
rd»
Ressources localisées
• Un dossier «.lproj» par locale
• Locale = langue + région (en_US, en_UK)
• Dans le dossier .lproj
• Images
• XIB
• Textes
5
Trad
uctio
n pa
r la
mét
hode
«st
anda
rd»
Fichiers «strings»
• Textes dans fichier «Localizable.strings»• /* Text to say hello */
"greetings" = "Welcome in Food Reporter!";
• /* Text to say hello */"greetings" = "Bienvenue sur Food Reporter !";
• NSLocalizedString• NSLocalizedString(@"greetings",@"Text to say hello")
• genstrings
• Outil de génération des fichiers .strings après analyse du code source
6
Trad
uctio
n pa
r la
mét
hode
«st
anda
rd»
En pratique
• Macro longue n’incitant pas à l’utiliser
• XIB compliqué pour le traducteur
• N’a pas forcément Interface Builder (ou ne maîtrise pas l’outil)
• Préfère un simple fichier texte
• genstrings peu pratique
• Ajout de texte au fur et à mesure des versions
• extraction et réinjection de chaînes dans les XIB (par ibtool) peu pratique
7
Trad
uctio
n pa
r la
mét
hode
«st
anda
rd»
Limitations de cette méthode
• Duplication des XIB
• Maintenance et évolutions complexe
• Modifications à répercuter pour chaque langue
• Compliqué pour le traducteur
• Un XIB unique ?
• Traduction des éléments un à un par code
• Nécessite d’avoir un IBOutlet sur chaque élément d’interface
8
La t
radu
ctio
n au
tom
atiq
ue d
e vo
tre
inte
rfac
e
La traduction automatiquede votre interface
• Principe
• Automatisation : éviter le glue code
• Aller plus loin
9
La t
radu
ctio
n au
tom
atiq
ue d
e vo
tre
inte
rfac
e
Principe
• Une méthode générique sachant traduire chaque type d’élément de l’UI
• Appeler à chaque chargement de XIB
• Appeler sur tous les éléments du XIB
10
La t
radu
ctio
n au
tom
atiq
ue d
e vo
tre
inte
rfac
e
Automatisation
• Sous-classer et surcharger• Pas pratique, et lourd à mettre en place
• Catégories• Pas fait pour, et aucune garantie
• Method Swizzling
But : appeler automatiquement la méthode
awakeFromNib
11
La t
radu
ctio
n au
tom
atiq
ue d
e vo
tre
inte
rfac
e
Automatisation
[obj awakeFromNib]; awakeFromNib { ??? }
[obj myAwakeFromNib];
-(void)myAwakeFromNib { [self autoL10n]; [self awakeFromNib];}
Method Swizzling : intervertir deux implémentations
12
[obj awakeFromNib]; awakeFromNib { ??? }
[obj myAwakeFromNib];
-(void)myAwakeFromNib { [self autoL10n]; [self myAwakeFromNib];}
Avant
Après
La t
radu
ctio
n au
tom
atiq
ue d
e vo
tre
inte
rfac
e
Automatisation! Method awakeFromNib = class_getInstanceMethod([NSObject class], @selector(awakeFromNib));! Method localizeNibObject = class_getInstanceMethod([NSObject class], @selector(localizeNibObject));! method_exchangeImplementations(awakeFromNib, localizeNibObject);
13
#define LocalizeIfClass(Cls) if ([self isKindOfClass:[Cls class]]) localize##Cls((Cls*)self)-(void)localizeNibObject {! LocalizeIfClass(UIBarButtonItem);! else LocalizeIfClass(UIBarItem);! else LocalizeIfClass(UIButton);! else LocalizeIfClass(UILabel);! else LocalizeIfClass(UINavigationItem);! else LocalizeIfClass(UISearchBar);! else LocalizeIfClass(UISegmentedControl);! else LocalizeIfClass(UITextField);! else LocalizeIfClass(UITextView);! else LocalizeIfClass(UIViewController);!! [self localizeNibObject]; // actually calls awakeFromNib as we did some method swizzling}
Lorsqu’un objet recevera le message awakeFromNib,c’est sa méthode localizeNibObject qui sera exécutée
Cette méthode va appeler une méthode différente en fonction du type d’élément.
La t
radu
ctio
n au
tom
atiq
ue d
e vo
tre
inte
rfac
e
Automatisation
14
Il suffit de traduire chaque type d’objet. Par exemple pour un label:
static inline void localizeUILabel(UILabel* lbl){ lbl.text = NSLocalizedString(lbl.text); }
pour qu’un UILabel soit automatiquement traduit,il suffira alors de lui mettre la clé de traduction dans son champ text.
De la même manière, pour un UITextField:
static inline void localizeUITextField(UITextField* tf){ tf.text = NSLocalizedString(tf.text); tf.placeholder = NSLocalizedString(tf.placehoder); }
Si on veut qu’un élément ne soit pas traduit, on peut imaginer rajouter un caractère précis devant le texte de cet élément, comme par exemple «$», et dans sa méthode
de localisation, ne le traduire que s’il ne commence pas par ce caractère.
La t
radu
ctio
n au
tom
atiq
ue d
e vo
tre
inte
rfac
e
Aller plus loin
• Personnalisation possible du code
• Vérifier les oublis de traduction
• Gérer les exceptions (chaînes fictives)
• Gérer les variantes singulier/pluriel
15
#define _T(x) NSLocalizedString((x),@"")#define _Tf(x,...) [NSString stringWithFormat:_T(x),__VA_ARGS__]#define _Tf_n(x,n,...) _Tf( (n<=1)?(x):(x"(+)") , n , ##__VA_ARGS__ )
NSString* s1 = _Tf_n(@"dish.comments.count",n);NSString* s2 = _Tf_n(@"user.dishes.count",n,userName);
"dish.comments.count" = "%d commentaire";"dish.comments.count(+)" = "%d commentaires";
"user.dishes.count" = "%2$@ a publié %$1d plat";"user.dishes.count(+)" = "%2$@ a publié %$1d plats";
Les
astu
ces,
les
pièg
es à
évi
ter
Les astucesLes pièges à éviter
• Impacts sur l’interface
• Intégration avec un SI
• Gérer l’ordre des paramètres
• Penser au formattage des nombres
• Suivi de version
16
Les
astu
ces,
les
pièg
es à
évi
ter
Impacts sur l’interface
• Différentes tailles selon la langue
• sizeToFit
• Images à taille variable
• stretchableImageWithLeftCapWidth:topCapHeight:
• Tester !!
17
Push
Les
astu
ces,
les
pièg
es à
évi
ter
Intégration avec un SI
• Applications utilisant un WebService
• Envoyer la locale au WS
• Utilisation de clés de localizable.strings dans le retour du WS
• Filtrage de contenu selon la locale
18
Les
astu
ces,
les
pièg
es à
évi
ter
Gérer l’ordre des paramètres
• 5 green apples
• NSLog(«%1$d %2$@ %3$@»,n,color,fruit)
• 5 pommes vertes
• NSLog(«%1$d %3$@ %2$@»,n,color,fruit)
19
Les
astu
ces,
les
pièg
es à
évi
ter
Formattage des nombres
• NSNumberFormatter
• séparateur de décimales, de milliers
• monnaie (currency)
• Utiliser les versions localisées des méthodes
• localizedStringWithFormat
• localizedDescription
• localizedScannerWithString
• ...
20
Les
astu
ces,
les
pièg
es à
évi
ter
Suivi de versions
• Version «live» pendant votre développement
• Version livrée aux divers traducteurs
• Versions itératives
• Attention aux chaînes liées avec le SI
• Plusieurs versions de votre application en circulation
21
Con
clus
ion
Conclusion
• Traduction d’application se fait en plusieurs étapes
• Internationalisation (i18n) : préparer les traduction (NSLocalizedString, ...)
• Localisation (L10n) : effectuer les traductions (créer un .strings par locale)
• Intégration d’une nouvelle langue pas si anodin
• Méthodes pour faciliter la traduction de XIB• Evite de multiplier les XIB pour chaque langue
• Facilite la communication avec vos traducteurs
22