Transcript
Page 1: CocoaHeads Rennes #1 : internationalisation

Traduction des interfaces de vos applications Cocoa

Olivier Halligon, avril 2011

Page 2: CocoaHeads Rennes #1 : internationalisation

Som

mai

re

Sommaire

• Introduction

• Traduction par la méthode «standard»

• La traduction automatiquede votre interface

• Astuces, pièges à éviter

• Conclusion

2

Page 3: CocoaHeads Rennes #1 : internationalisation

Intr

oduc

tion

Introduction

• Présentation

• Olivier Halligon

• Food Reporter

• Objectif

• Base de la traduction

• Traduction auto de XIB

3

Food Reporter

Page 4: CocoaHeads Rennes #1 : internationalisation

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

Page 5: CocoaHeads Rennes #1 : internationalisation

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

Page 6: CocoaHeads Rennes #1 : internationalisation

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

Page 7: CocoaHeads Rennes #1 : internationalisation

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

Page 8: CocoaHeads Rennes #1 : internationalisation

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

Page 9: CocoaHeads Rennes #1 : internationalisation

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

Page 10: CocoaHeads Rennes #1 : internationalisation

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

Page 11: CocoaHeads Rennes #1 : internationalisation

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

Page 12: CocoaHeads Rennes #1 : internationalisation

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

Page 13: CocoaHeads Rennes #1 : internationalisation

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.

Page 14: CocoaHeads Rennes #1 : internationalisation

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.

Page 15: CocoaHeads Rennes #1 : internationalisation

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";

Page 16: CocoaHeads Rennes #1 : internationalisation

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

Page 17: CocoaHeads Rennes #1 : internationalisation

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

Page 18: CocoaHeads Rennes #1 : internationalisation

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

Page 19: CocoaHeads Rennes #1 : internationalisation

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

Page 20: CocoaHeads Rennes #1 : internationalisation

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

Page 21: CocoaHeads Rennes #1 : internationalisation

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

Page 22: CocoaHeads Rennes #1 : internationalisation

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


Top Related