本文最初由Sean Berry撰写,由Ali Hafizji针对iOS 7进行了更新。php
开发一款伟大的iOS应用程序是件了不得的事情,可是还有比优秀的代码、华丽的设计以及直观化交互更多的事要作。跻身在App Store排行榜前列还须要正合时宜的产品营销、扩大用户群的能力、实用的工具以及尽量普遍地得到用户的技术。html
对不少开发者来讲,国际市场是过后的想法,但因为App Store提供了无缝的全球分享模式,任何iOS开发者均可以经过一键点击把应用程序发布至超过150个国家的市场。亚洲和欧洲表明了潜在客户不断增加的市场,这两个市场中不少人都不是以英语为母语,可是为了让应用充分利用市场的潜力,你至少要把应用语言国际化。ios
这篇教程将经过一款名为iLikeIt的应用带你了解最基础的国际化概念,并为你的应用添加国际化的支持。该示例应用有一个标签和一个You Like?按钮,用户不管什么时候点击You Like?,一些乐观的销售数据和对应的图片就会从按钮下方淡入显示。编程
不过如今,该应用仅仅有英语版本。浏览器
注意:国际化另外一个重要的方面是使用Auto Layout改变文本的大小。不过为了让本教程尽量地简单,咱们不会主要关注Auto Layout。对于Auto Layout这个话题,咱们另有其余教程。 |
国际化 vs 本地化(Internationalization vs Localization)app
在你开始学习本教程以前,很重要的一点是了解国际化和本地化之间的不一样之处,不少人常常会把这两个概念搞混。编辑器
简单说,国际化是一个应用程序国际兼容性设计的过程,好比:ide
1.以用户母语处理文本输入和输出;工具
2.处理不一样的日期、时间以及数字格式;学习
3.利用适当的历法和时区处理数据;
国际化是一项你和开发者经过利用系统提供的API来实现的活动,并在代码上作一些补充和修改,从而让应用的中文版、阿拉伯语版本和英文版同样好。
相比之下,本地化仅仅是把应用的用户界面和资源翻译成不一样的语言,这是你能够也应该交给别人作的工做,除非你能精通app应该支持的每种语言。
如今开始(Getting Started)
第一步是downloadiLikeIt项目,咱们将会在整个教程中使用它。
在Xcode 5中打开该项目,并在模拟器上运行,你将会看到如下界面:
从截图中看出,你须要本地化四个项目:
UI元素: Hello Label
UI元素: You like? Button
销售数据文本: Yesterday you sold 1000000 apps
图片文本: I LIKE IT
花一小会儿时间浏览文件和文件夹来熟悉下项目结构。 Main.storyboard包含单个屏幕,它是ViewController类的实例。
从代码中分离文本
目前,应用展现的全部文本都是以硬编码字符串存在于Main.storyboard和ViewController里。为了本地化这些字符串,你须要把它们放在一个单独的文件中。
你将会在包中简单地引用这些字符串,而不是在你的方法中进行硬编码。
Xcode使用带有".strings" 扩展名的文件来储存和检索app中使用的全部字符串,以支持每种语言。根据iOS设备当前使用的语言,代码中一个简单的方法调用将会查找并返回要求的字符数串。
试试看,打开 File>New>File,选择Resource中Strings Fils,如图:
点击下一步,为文件命名为Localizable.strings,而后点击save。
注意:Localizable.strings是iOS用来本地化文本默认的文件名称。请抑制以其余内容给它命名的冲动,不然之后你每次引用本地化字符串的时候要一次次输入.strings 文件名。 |
如今,你已经建立了Localizable.strings文件,你须要添加全部的文本--当前硬编码在app中的文本。你须要听从一个特定但简单的格式:
"KEY" = "CONTENT";
这些键/内容对功能就像NSDictionary ,惯例是使用默认的内容翻译做为内容的键:好比You Like?,你应该写:
"You like?" = "You like?";
Key/content对也能够包含格式化字符串:
"Yesterday you sold %@ apps" = "Yesterday you sold %@ apps";
如今切换至ViewController.m,找到viewDidLoad方法,如今app会为likeButton和salesCountLabel设置文本,展现以下:
_salesCountLabel.text = [NSString stringWithFormat:@"Yesterday you sold %@ apps", @(1000000)]; [_likeButton setTitle:@"You like?" forState:UIControlStateNormal];
取而代之的方法是,你须要今后前建立的Localizable.strings文件中读入字符串。用一个名为NSLocalizedString的宏修改这两行代码以下所示:
_salesCountLabel.text = [NSString stringWithFormat:NSLocalizedString(@"Yesterday you sold %@ apps", nil), @(1000000)]; [_likeButton setTitle:NSLocalizedString(@"You like?", nil) forState:UIControlStateNormal];
宏包将一个稍长的代码片断包裹为一个更易于管理的长度,它使用#define指令建立。若是你想知道NSLocalizedString宏是什么,可按住Control键并在NSLocalizedString点击,能够看到它的定义以下:
#define NSLocalizedString(key, comment) [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]
在当前的语言中,NSLocalizedString宏使用localizedStringForKey方法查找给定键值的字符串。它为table name传递nil,因此它使用默认的字符串文件名(Localizable.strings)。更多细节,可查看苹果的NSBundle Class Reference。
注意:这个宏把注释做为一个参数,但彷佛没什么用。不像此前那样须要手动把每一个key/value对键入Localizable.strings,你还可使用iOS SDK带的一个叫作genstrings的工具来自动处理(很是适用于大型项目)。 |
若是使用这个方法,你能够为每一个字符串加上一个注释,注释会显示在默认的字符串边上,做为translator的辅助。好比你能够添加一个注释指出字符串在哪里使用。
已经有了足够的背景信息,如今开始吧!
建立并运行你的项目,而且它应该像以前同样在主屏幕上展现相同的文本,可是西班牙文在哪里?如今你的应用已经进行了本地化设置,添加翻译是小事一桩。
添加西班牙语本地化(Adding a Spanish Localization)
想要添加支持另外一种语言,你能够点击左窗格中的iLikeIt项目文件夹,在旁边的窗格中选择Project(不是 Target),而后在Info标签下你会看到一个Localizations分区。点击点击“+”,而后选择Spanish (es)。
下个屏幕会询问你哪些文件须要本地化。选中全部文件并点击Finish。注意:Localizable.strings没有展现在这个列表中,不过不用惊慌!
在这一点上,Xcode已经在幕后设置好了一些目录,针对你选择的语言,这些目录包含不一样版本的InfoPlist.strings和Main.storyboard。你可使用Finder打开项目文件夹看看,你会看到如图所示:
看到en.lproj和es.lproj了吗?它们包含文件的特定语言版本。
en是English的本地化代码,es是Spanish的本地化代码。关于其余语言,可参看完整的语言代码列表。
从如今开始,当你的app想要得到某个文件的英文版,它就会去en.lproj中查找,而当它想要某个文件的西班牙语版时,它就会去es.lproj找。很是简单!把你的资源文件放在合适的文件夹里,剩下的事情就交给iOS负责了。
可是等等,Localizable.strings呢?想让Xcode知道你想将它本地化,那你能够在左窗格里选中文件,而后在右窗格中打开File Inspector。
你会看到一个Localize标签,点击并选择英语(由于当前是英语),最后点击Localize。
如今File Inspector面板将会展现文件所属的语言。目前,正如你所看到的,文件只针对英文进行本地化。可经过点击Spanish左边的框框添加西班牙语本地化。
回到左窗格并点击Localizable.strings旁边的箭头,它会显示出子元素。如今文件已经有了两个版本:一个是英文本,一个是西班牙语版。
想修改西班牙语的文本,可选择Localizable.strings (Spanish),并用以下内容替代它的内容:
"Yesterday you sold %@ apps" = "Ayer le vendió %@ aplicaciones"; "You like?" = "~Es bueno?~";
恭喜!如今你的应用支持两种语言了!
为了测试和验证全部事情都正常工做,你能够在模拟器/设备上把展现语言更改成Spanish,方法是打开设置应用,而后选择:General -> International -> Language -> Espanol.
若是 Xcode debugger仍在运行中,你能够在Xcode中点击“stop”,而后点击“Build & Run”,你将会看到:
地区vs语言(Locale vs Language)
100万是个至关不错的销售数据,咱们能够为它添加一些格式让它看起来更好!
打开ViewController.m并将为_salesCountLabel设置文本的代码行替换为:
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init]; [numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle]; NSString *numberString = [numberFormatter stringFromNumber:@(1000000)]; _salesCountLabel.text = [NSString stringWithFormat:NSLocalizedString(@"Yesterday you sold %@ apps", nil), numberString];
编译并运行应用程序,那么数字就会更容易辨认一些。
这对美国人来讲很是棒,但在西班牙,100万写做“1.000.000″而不是“1,000,000″。在西班牙文环境下运行应用程序,你将会看到逗号用来隔开0。在iOS中,数字格式化是基于地区/国家,而不是语言,因此为了了解某个西班牙人如何查看销售数据,可打开Settings.ap,并经过导航改变区域:General -> International -> Region Format -> Spanish -> Spain
在此编译和运行应用程序,如今你会看到正确的数字格式:
一点额外的前期工做,NSNumberFormatter会自动为合适的区域格式化你的数字。可能的状况下,请拒绝从新发明轮子,由于在iOS上,一般按照苹果的方式作才能有回报。
国际化Storyboards(Internationalizing Storyboards)
Storyboard中的元素,好比标签、按钮以及图片能够在代码中或者直接在storyboard中设置。在设置文本编程时,你已经学会了如何支持多种语言,可是屏幕顶部的“Hello”标签没有IBOutlet,只能在Main.storyboard中设置它的文本。
你能够添加一个IBOutlet,将其链接到Main.storyboard中的label上,而后使用NSLocalizedString设置其文本属性,就像使用likeButton和 salesCountLabel那样,可是这里有一个本地化storyboard元素更简单的方法,不须要任何附加代码。
打开Main.storyboard左侧的小三角形,你会看到Main.storyboard (Base)和Main.storyboard (Spanish)。点击Main.storyboard (Spanish)打
开编辑器,你会看到storyboard中的本地化文本。你已经有了一个Hello标签入口,以下:
/* Class = "IBUILabel"; text = "Hello"; ObjectID = "pUp-yc-27W"; */ "pUp-yc-27W.text" = "Hello";
用西班牙语翻译的“Hola”替换两个“Hello”:
/* Class = "IBUILabel"; text = "Hola"; ObjectID = "pUp-yc-27W"; */ "pUp-yc-27W.text" = "Hola";
注意:绝对不要直接改变自动生成的ObjectID,也不要复制和粘贴上边的代码行,由于标签的ObjectID可能已经跟上边展现的不同了。 |
图片的国际化(Internationalizing Images)
因为应用程序使用了包含英语文本的图片,因此你须要把图片本地化,由于零零散散的英文文本会让你的西班牙应用看起来很不专业,而且也有损于应用的总体易用性和市场潜力。
本地化图片,首先须要下载西班牙语版本的图片(在大多数浏览器上是右键点击>保存为):
打开Images.xcassets,拖放此前下载的图片megusta.png并添加至左侧的图片列表,从而把图片添加至资产Asset catalog。Asset catalogs不能被国际化,因此你须要有一个方法来本地化图片。
打开Localizable.strings (English) ,并添加以下内容:
"imageName" = "ilike";
把如下代码添加至Localizable.strings (Spanish)文件:
"imageName" = "megusta";
从如今开始,你将使用imageName key来检索本地化版本的图片。打开ViewController.m并把以下代码添加到viewDidLoad方法中:
[_imageView setImage:[UIImage imageNamed:NSLocalizedString(@"imageName", nil)]];
若是须要,将模拟器/设备切换到西班牙语,编译并运行,而后你会看到本地化图片的展现。
如今你已经有了将应用程序针对多种不一样语言本地化所需的全部工具。
注意:这仅适用于每种语言有不一样文件名的状况。一个更好的方法是本地化资源文件夹,如这篇文章所描述的那样。 |
额外奖励
做为最后的奖励,咱们来本地化应用的名字。Info.plist有一个特殊的文件(InfoPlist.strings),你能够在里边用字符串覆盖其余语言。为给应用程序一个不一样的西班牙语名字,可打开Supporting Files > InfoPlist.strings (Spanish),并插入如下代码:
"CFBundleDisplayName" = "Me Gusta";
它改变了应用的名称,像Springboard上展现的那样。
练习:国际化音频文件(Exercise: Internationalizing Audio files)
学习到这里,你应该熟悉了基本的国际化知识。这是一个简单的练习,你能够经过两个不一样的音频文件(一个是英文版,一个是西班牙语版)来测试下本身新掌握的知识,并基于用户选择的语言播放合适的文件。
如下是必要步骤的简单描述:
1.下载示例音频文件(sample audio files)。
2.把box-en.wav首个音频文件拷贝到项目中。
3.打开音频文件inspector,选择本地化按钮,确保你选择了英语和西班牙语做为支持语言。
4.重命名第二个音频文件(box-es.wav),和第一个名字(box-en.wav)同样,而后将其拷贝到es.Iproj文件夹。
5.确保你在Finder提示中选择了“Replace File”。
何去何从
Final Project包含了你在该教程中所写的所有代码。
如今你知道了国际化一款iPhone app所需的基本技术,那就为你现有的应用添加外语支持吧,或者在设计下一款应用时为其添加一门外语支持。正如你所看到的那样,这几乎没有花费多少时间,而它将会让你的应用接触到更宽广更多样化的受众,而且你的非英语用户也会感谢你!
对于实际的翻译,你可使用Google的免费翻译服务(http://www.google.com/translate),但结果可能不是丝绝不差的。若是你能够花点钱,那么你能够考虑苹果的Internationalization and Localization页面下方列出了第三方服务提供商。
若是你有任何关于国际化的问题或建议,请加入论坛讨论!