iPhone开发基础教程笔记(十七)--第十七章 应用程序本地化

第十七章 应用程序本地化
iPhone拥有健壮的本地化(localization)体系结构,使用它不但可以将应用程序(或者由其他程序将它)翻译成多种语言,甚至可以翻译成同一语言的多种方言。想为英式英语使用者和美式英语使用者提供不同的术语吗?没问题。

17.1  本地化体系结构
在运行非本地化应用程序时,应用程序的所有文本都会以开发人员自己的语言呈现,也就是“开发基础语言”。
当开发人员决定对其应用程序进行本地化时,他们会在应用程序束中为每种支持的语言创建一个子目录。每种语言的子目录都包含有一个翻译为此种语言的应用程序资源子集。每个子目录都被称为一个“本地化项目”,也称为“本地化文件夹”。本地化文件夹通常使用.lproj作为其扩展名。
在Settings应用程序中,用户可以设置语言和区域格式。例如,如果用户语言是英语,那么可选地区可以是美国或澳大利亚等--即所有讲英语的地区。
当本地化的应用程序需要载入某一资源时,如图像、属性列表或nib文件,应用程序会检查用户的语言和地区,并查找与此设置相匹配的本地化文件夹。如果找到了相应的文件夹,那么他会载入此资源的本地化版本而不是基础版本。
对于选择法语做为iPhone语言,选择法国作为地区的用户,应用程序会先查找名为fr_FR.lproj的本地化文件夹。文件夹名称的前两个字母是ISO二位代码,表示法语。下划线后的两个字母是ISO国家(地区)代码,表示法国。
如果应用程序找不到匹配的二位代码,那么他会查找匹配的ISO三位代码。所有的语言都有三位代码。只有一部分语言有二位代码。

说明:在ISO网站上可以找到当前ISO国家(地区)代码列表。二位和三位代码都是ISO3166标准的一部分:
http://www.iso.org/iso/country_codes.htm

在之前的示例中,如果应用程序找不到名为fr_FR.lproj的文件夹,他会查找名为fre_FR或fra_FR的本地化文件夹。所有语言都至少有一个三位代码。某些语言有两个三位代码,一种是此语言的英语拼写,一种是本地拼写。当一种语言既有二位代码又有三位代码时,则使用二位代码。
如果应用程序找不到精确匹配的文件夹,那么他会随即查找应用程序束中仅语言代码匹配(地区代码不匹配)的本地化文件夹。因此,对于来自法国的讲法语的人,应用程序随后会查找名为fr.lproj的本地化项目。如果找不到此名称的语言项目,他会尝试查找fre.lproj,然后查找fra.lproj。如果都找不到,他会查找French.lproj。最后一种结构是为了支持旧式Mac OS X应用程序,一般来说,应用程序会避免使用它(此规则也有例外,我们稍后讲述)。
如果应用程序找不到与语言/地区的组合相匹配或仅有语言相匹配的语言项目,那么他会使用开发基础语言中的资源。如果找到了适合的本地化项目,那么对于任何所需要的资源,他将总是先查找这里。例如,若载入一个使用imageNamed:的UIImage,他先会在本地化项目中查找使用指定名称的图像。如果找到了此图像,他就会使用它。如果没有找到,他将会退回到基础语言资源。
如果某个应用程序与多个本地化项目相匹配,例如,一个名为fr_FR.lproj的项目和一个名为fr.lproj的项目,那么他会先在更精确的匹配中查找,在本例中是fr_FR.lproj。如果在此处找不到资源,他将会查找fr.lproj。这样便可以在一个语言项目中对所有此语言的使用者提供共有的资源,仅本地化受到不同方言或地理地区影响的资源。
你只需要本地化受到语言或国家(地区)影响的资源。如果应用程序中的图像没有使用词汇并且其含义是通用的,那么就没有必要本地化此图像。

17.2 使用字符串文件
在源代码中,字符串文字和字符串常量有何作用?下面参考第十六章中的一段源代码:
UIAlertView *alert=[[UIAlertView alloc]
 initWithTitle:@"Error accessing photo library"
  message:@"Device does not support a phto library"
   delegate:nil
   calcelButtonTitle:@"Drat!"
   otherButtonTitles:nil];
[alert show];
[alert release];

如果我们已经努力完成了对特定受众的应用程序本地化工作,我们当然不想看到出现以开发基础语言编写的警告。
上面问题的答案是,将这些字符串存储到特定的文本文件中,即字符串文件中。字符串文件实际上是Unicode(UTF-16)文本文件,其中包含了字符串配对列表,每项都标识了注释。

下面的示例描述了应用程序中字符串文件的格式。

/*Used to ask the user his/her first name */
"First Name"="First Name";

"Last Name"="Last Name";

"Birthday"="Birthday"

/* */之间是注释,他们对应用程序来说没有用处。等号左侧的字符串充当键,等号右侧的值是用于翻译的本地语言。因此,如果将前面的字符串文件本地化为汉语,可能会是这样:

"First Name"="姓";

"Last Name"="名";

"Birthday"="生日"

创建字符串文件
我们不会手动输入来创建字符串文件。而是,将所有本地化的文本字符串嵌入到代码内特定的宏中。完成源代码并做好本地化的准备工作之后,可以运行一个名为genstrings的命令行程序,他将在所有代码文件中搜索出现的宏,提取出所有的字符串,并将他们嵌入到本地化的字符串文件中。
下面显示了宏如何工作。我们从传统的字符串声明开始:

NSString *myString=@"First Name";

要本地化此字符串,需要这样做:

NSString *myString=NSLocalizedString(@"First Name",@"Used to ask the user his/her first name");

NSLocalizedString宏使用了两个参数。第一个参数是基础语言中字符串的值。在未本地化的情况下,应用程序将使用此字符串。第二个参数是注释。
NSLocalizedString在合适的本地化项目内部的应用程序束中查找名为localizable.strings的字符串文件。如果没有找到此文件,则返回其第一个参数,而此字符串会出现在开发基础语言中。如果此应用程序没有本地化,则字符串通常仅在开发时显示在基础语言中。
如果NSLocalizedString找到了字符串文件,则会搜索此文件中与第一个参数相匹配的行。在前面的示例中,NSLocalizedString将在字符串文件中搜索字符串"First Name"。如果在本地化项目中没有找到与用户语言设置相匹配的项,他会在基础语言中查找字符串文件并使用其中的值。如果没有字符串文件,他会只使用传递给NSLocalizedString宏的第一个参数。

17.3 现实中的iPhone:本地化应用程序
现在创建一个显示用户当前“区域设置”的小应用程序。区域设置(NSLocal实例)同时描述了用户的语言和地区。在与用户交互时,系统使用区域设置确定使用哪种语言及如何显示日期、货币和时间信息等。创建应用程序之后,需要将它本地化为其他语言。在此可以学习到如何本地化nib文件、字符串文件、图像,甚至是应用程序图标。程序界面的顶部 显示用户的区域设置。然后下面的左侧的词设置为静态标签,使用输出口将视图下发右侧的词设置为可编程的。屏幕底部是一幅旗帜图像--一幅静态UIImageView。

现在开始实际操作。在Xcode中基于视图创建新项目-LocalizeMe。查看17 LocalizeMe文件夹,从其Resources/Base Language/中找到icon.png和flag.png。将其添加到自己的Resources文件夹中。然后单击Info.plist,并将Icon file值设置为icon.png,即可以将图标图像用作应用程序图标。
6个标签都需要创建输出口:1个用于视图顶部的蓝色标签,5个用于下方右侧的词条。打开Classes中的LocalizeMeViewController.h:
声明IBOutlet标签和@property

然后双击LocalizeMeViewController.xib,设置界面 输出口。

然后打开LocalizeMeViewController.m:

- (void)viewDidLoad {
 NSLocale *locale=[NSLocale currentLocale];
 NSString *displayNameString=[locale displayNameForKey:NSLocaleIdentifier value:[locale localeIdentifier]];
 localeLabel.text=displayNameString;

 label1.text=NSLocalizedString(@"One",@"The number 1");
 label2.text=NSLocalizedString(@"Two",@"The number 2");
 ...
 [super viewDidLoad];
}

...
@end

在此类中唯一需要查看的是viewDidLoad方法。在此首先要做的事情是获取一个代表用户当前区域设置的NSLocale实例,区域设置在iPhone的Settings应用程序中进行设置,它包含了用户的语言和地区偏好。

 NSLocale *locale=[NSLocale currentLocale];

17.3.1 查看当前区域设置
NSLocale的工作原理就像一本字典。其中包含关于当前用户偏好的成批信息,包括所使用的货币名称和期望的日期格式。在NSLocale的API参考中可以找到这些值的完整列表。
在代码的下一行中,可以找到区域设置标识符,即此区域设置所代表的语言和/或地区的名称。在此使用的函数叫displayNameForKey:value:。对于以特定语言请求的项,使用此方法可以返回此项的值。
例如,法语的显示名称在法语中是Francais,但在英语中是French。使用此方法可以找到任何关于区域设置的数据,以便对任何用户进行正确的显示。在此例中,所获取的是使用区域设置语言的区域设置显示名称,所以为第二个变量传递了[locale localeIdentifier]。localeIdentifier是一个字符串,其格式是之前创建语言项目时所使用的格式。对于美式英语使用者来说,他是en_US;对于法国的法语使用者来说,他是fr_FR。

 NSString *displayNameString=[locale displayNameForKey:NSLocaleIdentifier value:[locale localeIdentifier]];

有了显示名称,就可以用它设置视图顶部的标签。

 localeLabel.text=displayNameString;

然后,以开发基础语言将其他5个标签依次编号为1至5.此处还有注释解释每个词的意思。

 label1.text=NSLocalizedString(@"One",@"The number 1");

17.3.2 测试LocalizeMe

现在,运行此应用程序。可以使用仿真器对此进行测试。仿真器似乎隐藏了某些语言和地区设置,因此你也许更想在设备上完成测试。
使用NSLocalizedString宏代替静态宏,为本地化做好了准备,但还没有开始本地化。如果使用仿真器或iPhone上的Settings应用程序更改为另一种语言或另一个地区,那结果看上去应该基本相同,除了视图顶部的标签。

说明:如果在启动此应用程序时遇到了问题,可以尝试按照本章其他部分中的本地化步骤去。如果不起作用,可以参考网站
http://iphonedevbook.com 

17.3.3 本地化nib文件

现在开始本地化nib文件。本地化任何文件的基本步骤都是一样的。单击LocalizeMeViewController.xib,然后Cmd+1打开其Info窗口。查看其General选项卡,单击窗口左下角的Make File Localizable按钮。

单击Make File Localizable按钮之后,窗口不会切换到Targets选项卡。关闭Info窗口,并查看Groups&Files窗格。注意,现在LocalizeMeViewController.xib文件旁有一个展开三角形,表示他是一个组或文件夹。展开他进行查看。

17.3.4 查看本地化的项目结构
在该项目中,LocalizeMeViewController.xib有一个子值--English。他由系统自动创建,代表开发基础语言。打开Finder并打开LocalizeMe项目文件夹。在此应该可以看到一个名为English.lproj的新文件夹。
在写作此书时,Xcode仍然对开发基础语言使用旧项目名称---English.lproj,而非沿用苹果公司使用ISO双字母语言代码的本地化传统,如果使用此传统,那么将会生成名为en.lproj的文件夹。此问题列于Xcode3.1版本说明中。因为他运行得很好,所以没有必要更改此名称,但在添加新本地化时需要使用ISO代码。
再次单击Groups&Files窗格中的LocalizeMeViewController.xib,然后按Cmd+1返回到Info窗口。返回至General选项卡,并单击Add Localization按钮。此时会弹出一个下拉表单,用于输入新本地化的名称。在此要为法语添加本地化,所以键入fr。不要在下拉菜单中选择French,因为这样将使用旧名称French。

提示:在处理区域设置时,语言代码是小写的,但是国家(地区)代码是大写的。因此,用于法语项目的正确名称是fr.lproj,但用于本土法语(在法国的人说的法语)的项目是fr_FR.lproj,而不是fr_fr.lproj或FR_fr.lproj。在Mac OS X中,文件系统不区分大小写,因此所有的选项都可以起作用,但iPhone的文件系统是区分大小写的,因此正确的匹配大小写非常重要。

按下回车键之后,Xcode将在名为fr.lproj的项目文件夹中创建一个新本地化项目,并将LocalizeMeViewController.xib复制到此处。在Groups&Files窗格中,LocalizeMeViewController.xib应当有两个子值,English和fr。双击fr打开向法语使用者显示的nib文件。
在IB中打开的nib文件与以前建立的文件完全相同,因此这是它的一个副本。对此文件所做的任何更改都会向法语使用者显示,所以需要双击左侧的各个标签,将他们由One、Two、Three...改成 Un、Deux...。完成更改之后,请保存此nib文件,并返回至Xcode。现在,nib文件已经本地化为法语。编译运行程序,启动之后,轻按主菜单按钮,打开Settings应用程序并更改语言和地区偏好。将Region Format由United States改为France(在French行的下面),然后将Language由English改为French。一般先更改Region Format,因为一旦更改了语言,iPhone将重启并返回至主菜单。现在iPhone已经设置为使用法语,因此需要再次启动LocalizeMe。这时左侧的单词应该显示为法语。

注意:iPhone和iPhone仿真器都隐藏了资源以提升性能。因此,有时需要手动移除旧版本的应用程序,进行清理及生成工作以显示本地化更改。在仿真器上有一个小技巧:退出仿真器。然后,在Xcode的Build菜单中选择Clean。然后,打开Finder,删除文件夹~/Library/Application Support/iPhone Simulator。现在从此书中打开一个旧项目,并在仿真器上运行。他启动之后,轻按主菜单按钮,启动Settings,将地区改为France,语言改成French。做出改动之后,退出仿真器。最后,返回值LocalizeMe项目并在仿真器上运行。大功告成!

现在的问题是,国旗错了。通过在French本地化nib文件中选择一副不同的图像就可以更改国旗图像。除此之外,也可以真正的本地化国旗本身。在本地化nib文件使用的一副图像或其他资源时,nib文件会自动显示正确的语言版本。如果使用French版本本地化flag.png文件本身,那么在适当的时候,nib文件会自动显示正确的国旗。

17.3.5 本地化图像
首先在Xcode的Groups&Files窗格中单击flag.png。然后Cmd+1返回到此文件的Info窗口,单击Make File Localizable。这样做可以让Xcode将flag.png复制到English.lproj文件夹(或是基础语言文件夹中,如果他们不同的话)。切换回General选项卡,并单击Add Localization。在提示输入语言时,键入fr。此时,在LocalizeMe项目文件夹内的fr.lproj文件夹中应该有另一个文件,叫做flag.png,这是基础语言中的flag.png文件的一个副本。显而易见,此图像并不正确。既然Xcode不允许编辑图像文件,那么在本地化项目内获取正确图像的最简便的方法就是使用Finder将正确的图像复制到项目中。在17 LocalizeMe文件夹的Resources文件夹中,可以找到一个名为fr的文件夹。在此子文件夹中,可以找到一个flag.png文件,将此flag.png复制到项目的fr.lproj子文件夹中,改写原文件。
工作完成了。因为iPhone可能会在上次运行应用程序时隐藏美国国旗,所以需要使用Xcode中的Organizer窗口将旧应用程序从iPhone中移除。如果是在仿真器上运行,则不必如此,只需直接跳到清理及生成步骤。
Window菜单=》Organizer,在Summary选项卡上,可以看到3个部分。最下面部分的标签是Applications。在应用程序列表中,找到LocalizeMe并选定他,然后单击减号按钮移除应用程序的旧版本和与之关联的隐藏程序。
现在从Build菜单=》Clean,再次生成并运行此应用程序。

17.3.6 本地化应用程序图标
可以使用与本地化flag.png同样的方式来本地化应用程序图图标图像。

17.3.7 生成和本地化字符串文件
现在视图右侧的单词仍然是英语。翻译他们需要先生成基础语言字符串文件,然后对她本地化。要完成这一任务,需要暂时脱离Xcode的温柔陷阱。
启动/Applications/Utilities/中的Terminal.app。当终端窗口打开时,键入cd加一个空格,不要按回车键。
现在打开Finder,将LocalizeMe项目文件夹拖动到终端窗口中。放置之后,至项目文件夹的路径已经显示了,这时再按回车键。
下一步是运行程序genstring,使之查找Classes文件夹中的.m文件中出现的所有NSLocalizedString。谓词,只需要键入以下命令:

genstrings ./Classes/*.m

命令执行完之后,在Finder中,在项目文件夹中找到一个名为Localizable.strings的新文件。将它拖到Xcode中的Resources文件夹中,但在弹出提示时,先不要单击Add按钮。

提示:任何时间都可以安全地重新运行genstrings以重新创建基础语言文件。一般来说,不应该编辑基础语言文件。如果需要对任何用到的字符串作出更改,请在代码中查找它并在此处进行更改;然后使用genstrings重新生成Localizable.strings文件。

Localizable.strings文件采用UTF-16编码,这是Unicode的二字节版本。多数人可能使用UTF-8或当地语言编码方案做为Xcode中的默认编码。所以在项目中导入Localizable.strings文件时,需要考虑到这一点。首先,取消选中Copy items into destination group's folder(if needed)复选框,因为此文件已经在项目文件夹中。更重要的一点是,将文本编码更改为Unicode(UTF-16)。如果不这样做的话,在Xcode中编辑此文件会显示乱码。
然后单击Add按钮。导入文件之后,在Resources中单击Localizable.strings并查看它。他应该包含5个条目,因为我们对5个不同的值使用了5次NSLocalizableString。

现在对她进行本地化。
首先单击Localizable.strings,并按Cmd+1打开Info窗口,切换到General选项卡,便可以发现其中的Make File Localizable按钮。单击它。切换回General选项卡并单击Add Localization。在提示输入语言时,键入fr表示对法语的所有方言进行本地化。返回至Groups&Files窗格,单击Localizable.strings旁边的展开三角形。单击fr,并在Xcode的编辑窗格中做如下更改:

"Five"="Cinq"
...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值