Lancer une appli dans une autre langue que celle du système
laurris
Membre
Tout est dans le titre. Dans Xcode, je sais qu'il faut passer des arguments dans la info Window de l'executable , mais lesquels ?
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Je savais pas qu'il était possible de le faire directement depuis xCode. Si quelqu'un à l'info pour savoir comment faire depuis xCode je suis preneur également.
gnome: Dans la section "Executables", tu double cliques sur l'executable voulu. Dans la fenêtre d'infos, vas dans le tab "Arguments" et ajoute un argument -AppleLanguages "(French)" sur une seule ligne. C'est tout.
Y'a une page qqpart dans la doc qui listerait ce genre de "clés" / arguments pris en compte ?
Dans le User Defaults Programming Topics For Cocoa il y a des infos au sujet des arguments que l'on peut transmettre en paramètre au lancement d'une application, plus précisément sur cette page au chaptire Argument Domain : http://developer.apple.com/documentation/Cocoa/Conceptual/UserDefaults/Concepts/DefaultsDomains.html
Sinon puisque l'on parle d'internationalisation je cherchais de mon côté s'il était possible (sans réinventer la roue) de changer de langue à la volée c'est à dire sans relancer l'application. Il semble d'après mes recherches que c'est impossible, à moins que je me trompe ?
RE-EDIT :
Plus d'infos grâce à la commande defaults on peut connaà®tre les clés du NSGlobalDomain et leur valeur :
ou mieux :
Ah oui j'aurais pas pensé à regarder dans les UserDefaults, je les connait mais je pensais pas que c'était caché là pour ce cas des langues... Mais bon en effet c'est logique au final.
je pense que c'est possible, d'ailleurs quand je lance Adium chez moi il commence par avoir les menus en anglais le temps qu'il se charge... puis finit par les passer en français une fois qu'il est chargé... Donc j'ai bien l'impression qu'il change de langue dynamiquement (car s'ils utilisaient le mécanisme automatique de Cocoa qui charge direct le bon NIB dans la bonne localisation, ça s'afficherait direct en français)
En cherchant du côté de NSBundle et NSNib, il suffit de faire le chargement de ton NIB à la main en précisant la localisation, c'est tout à fait possible. Un peu plus lourd qu'avec la version automatique (genre mettre le nom du mainNibFile dans le plist de ton appli pour qu'il charge le NIB tout seul), mais tout à fait possible.
Genre utiliser NSBundle et sa méthode (de "NSBundle Additions") [tt]+ (BOOL)loadNibFile:(NSString *)fileName externalNameTable:(NSDictionary *)context withZone:(NSZone *)zone[/tt]... en passant comme chemin en paramètre le résultat d'un appel à [tt]- (NSString *)pathForResource:(NSString *)name ofType:(NSString *)extension inDirectory:(NSString *)subpath forLocalization:(NSString *)localizationName[/tt].
Du coup en faisant comme ça tu peux passer la localisation souhaitée en paramètre.
Pour le chargement dynamique des ressources NSBundle et NSNib sont très pratiques en effet mais ce que j'ai du mal à concevoir c'est comment remplacer un .xib déjà chargé par un autre d'une autre langue, surtout pour le MainMenu.xib qui contient en général la barre des menus et qui est le seul .xib requis dans un appli cocoa...
Je vais creuser tout cela et dès que j'ai un peu de temps essayer de coder un petit proof of concept de cette idée pour voir si c'est réalisable sans trop contourner les faciliter de localisation offertes par cocoa.
Après tout, un NSNib est un objet comme un autre, il a un alloc/init mais il a aussi un dealloc. Si tu envoies un "release" à ton objet NSNib (correspondant à ton MainMenu.nib) ça devrait le décharger. Ensuite tu charges celui de l'autre langue à la place. En passant dans le dictionnaire "externalNameTable" (qui sert à indiquer les objets à utiliser pour remplacer les proxys comme "File's Owner" par exemple) le même que celui qui était passé à ton ancien MainMenu.nib j'imagine que tu dois retrouver à peu près tes petits.
Bon après bien sûr faut faire gaffe, tu ne remplaces pas de façon transparente un NIB par un autre (d'autant que rien ne garantit à Cocoa que ton NIB anglais et ton NIB français ont la même cohérence, tu peux avoir oublié un outlet dans une des deux versions ou ne pas avoir les mêmes TopLevelObjects pour les deux versions de ton NIB (en/fr) parce que t'as fait évoluer la version anglaise mais t'as oublié de modifier la fr en conséquence... Donc l'opération ne peux que consister à décharger le premier NIB et charger le second NIB, donc en prenant soin de pas détruire des objets plus tôt qu'ils ne devraient (car releasés par le NIB déchargé)...
Donc bon faut faire gaffe à envoyer un retain aux objets que tu veux garder avant de décharger l'un et charger l'autre, puis envoyer un release une fois que l'échange de NIB est fini pour balancer... Et surtout aussi avoir conscience que les objets qui ont été instancié par le NIB lui-même (genre ton instance de AppController que tu aurais créé dans le NIB dans IB) ne seront plus les mêmes d'un NIB à l'autre (instances différentes, et envoyer un retain avant et un release après n'y changera rien)... donc prendre les précautions qui s'imposent et vérifier que ça pose pas de soucis, en particulier ne mettre dans ce "typique cube bleu" que les connexions entre ta GUI et les IBActions mais prendre soin de ne pas y stocker la partie modèle de ton MVC...
Bref, faut quand même prendre les précautions et s'imposer une séparation propre pour ne mettre dans tes NIBs que ce qui concerne vraiment l'interface. Après, décharger un NIB et en charger un autre à la place et faire pointer tes variables sur les nouvelles instances au lieu des anciennes c'est pas trop méchant sinon sur le principe. Pas courant comme cas, mais jouable.
En tout cas si je pousse l'idée, ça fera surement un topic de plus sur le forum