第十六章: 本地化
当你创建了一个非常有用的程序后,你希望把它分享给世界上更多的人. 不幸的是,我们不是一个母语. 假如我们希望讲法文的朋友能使用RaiseMan 程序. 那我们就会说:""我需要对RaiseMan进行法文本地化"
如果我们的程序被世界上人们所用,那么我们至少需要本地化下面这些语言: English,French,Spanish,GerMan,Dutch,Italian,Japanese和chinese. 我们不需要为每个语言重新编写我们的程序.实际上,我们不需要重新编写任何Objective-C代码.也就是说, 世界上所有的国家和民族可以和平友好的使用同一个可执行包.
与创建多个可执行包相反,我们将创建string table来本地化resource.在工作目录中,English.lproj 目录包含了所有的English语言本地化资源: nib文件,图像,和声音. 为了本地化法语,我们需要添加French.lproj目录, nib,图像以及声音当然是法文的. 在运行的时候程序会根据用户在language preference中语言的设定来自动加载对应的resource. [自动体现在resource 的名字,English.lproj French.lproj]
那么在程序中那些地方需要使用到语言本地化呢?举个例子,在MyDocument.m,有以下代码:
NSAlert *alert = [NSAlert alertWithMessageText:@"Delete defaultButton:@"Delete" alternateButton:@"Cancel" otherButton:nil informativeTextWithFormat:@"Do you really want to delete %d people?", [selectedPeople count]];对于每个语言,我们将要有一个string table. 并请求NSBundle查找string, NSBundle将自动根据用户的language preference的设定来查找正确的语言版本如图16.1
--本地化nib文件--
在XCode中,选择-不要打开-Mydocument.nib, 打开它的Info panel. 点击Add Localization 按钮如图16.2在地区提示选择框中选择 French.
通过Finder,我们可以发现这时候会在French.lproj下创建了English.lproj/MyDocument.nib的副本.在XCode,Resources组下面,我们可以看到两个版本的MyDocument.nib: English和French.如图16.3 .双击打开French版本
将window修改成如图16.4
我们需要使用Option键来输入重音字符. 例如要输入é,按住Option键,输入e, 然后再次输入e.(在System Preferences 的International面,你可以在你的输入菜单上添加Keyboard Viewer,如果你需要输入大量的非常规字符,Keyboard Viewer能帮助你学习那些组合键能输入那些字符 )现在,你已经创建一个本地化资源. 注意,如果你改变了你的程序[UI 改变了],你就可能要修改道所有的nib文件(French和English版本).所以,等程序开发并测试通过后在去本地化它.
编译程序.在运行前,打开System Preferences的International面,设置Françis语言.然后运行,这是程序会自动加载了French版本的资源
同样, Document架构同时以及完成了一些本地化.例如,当你关闭一个没有存储的document, 将会有French版本的询问信息出现的
String Tables对于每个语言版本,你可以创建多个string table. 一个string table就是一个以后缀名为.strings的文件.比如,如果你有一个Find Panel,那么你可以创建不同语言版本的find.strings文件来本地化这个Find Panel, 例如其中的None found字符串string table 其实就死一些key-value组. key和value都以双引号包起来,每组key-vaule以分号结束如:
"Key1" = "Value1";"Key2" = "Value2";你可以通过NSBundle来找到对应key值的vaule.
NSBundle *main = [NSBundle mainBundle];NSString *aString = [main localizedStringForKey:@"Key1" value:@"DefaultValue1" table:@"Find"];上面的代码会在Find.strings中查找"Key1"对应的vuale字符串. 如果没有提供用户指定的语言的本地化资源,那么就会查找第二个所选语言,如果第二个也没有本地化资源,就依次找下去. 如果到最后还是没有找到,那么 ""DefaultValue1"将会返回. 如果你没有提供string table的名字,将使用Localizebale作为string table的名字. 所以,大部分程序都会每个支持的语言提供一个string table - Localizable.strings
-- 创建string table --
我们来给English创建一个Localizable.strings文件,在XCode中选择New File..菜单,创建一个empty文件并命名为Localizable.strings. 将它保持在Englisth.lproj目录中,如图16.5编辑该文件,添加下面内容:
"DELETE" = "Delete";"SURE_DELETE" = "Do you really want to delete %d people?";"CANCEL" = "Cancel";保存(不要忘记了分号噢)现在来French本地化这个文件。选择Localizable.strings文件,打开它的Info Panel,创建本地化如图16.6
编辑文件如下:"DELETE" = "Supprimer";"SURE_DELETE" = "Etes-vous sûr de vouloir effacer ces %d personnes ?";"CANCEL" = "Annuler";为了保存非一般字符,你要选择Unicode(UTF-8)的文件压码。 在French.lproj/Localizable.strings的info panel中,设置文件压码为UTF-8.在弹出的panel上,单击Convert按钮如图16.7
保持文件-- 使用Strings table --
app只有一个string table,可以这样来调用,如下NSString *deleteString;deleteString = [[NSBundle mainBundle] localizedStringForKey:@"DELETE" value:@"Delete?" table:nil];幸运的是,在NSBundle.h定义了一个宏帮助完成#define NSLocalizedString(key, comment) [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]在MyDocument.m中,找到弹出Alert Panel的地方,使用下面代码替换
NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"DELETE", @"Delete") defaultButton:NSLocalizedString(@"DELETE", @"Delete") alternateButton:NSLocalizedString(@"CANCEL", @"Cancel") otherButton:nilinformativeTextWithFormat:NSLocalizedString(@"SURE_DELETE", @"Do you really want to delete %d people?"), [selectedPeople count]];编译程序,将系统语言修改为French。然后运行App,当删除table中的一条记录,你就看到了一个French版本的Alert Panel。 思考:ibtool很显然,当你本地化很多程序时,你将需要做很多的翻译工作。如果有一个自动化工具,帮你被这些翻译stirng贴到nib文件中,就会节省很多工作。 ibtool就是其中一个从terminal运行ibtool命令,它可以列举一个nib文件中的类或对象,也可以把其中的本地化字符串抽取出来到一个plist文件。 下面的例子时将English.lproj/MyDocument.nib文件中的本地化字符串抽取到文件Doc.strings文件中
> cd RaiseMan/English.lproj> ibtool --generate-stringsfile Doc.strings MyDocument.nibDoc.strings文件如下:
"100026.headerCell.title" = "Name";这时,我们可以创建Spanish版本的nib文件。先生成Spanish版本的Doc.strings,如下
"100026.headerCell.title" = "Nombre";然后生成Spnish版本的nib
> mkdir ../Spanish.lproj> ibtool --strings-file Doc.strings --write ../Spanish.lproj/MyDocument.nib MyDocument.nib你可以输入man ibtool来获得ibtool的帮助
> man ibtool