【译】Xcode 6下的iOS应用本地化

最近做iOS应用的国际化,找资料时这篇文章给我的帮助最大,也觉得它讲得最透彻,现在尝试翻译成中文。第一次翻译希望能翻好,末尾会加一点我做国际化与本地化时遇到的问题与解决方法。
原文作者Ryan Hodson
原文链接Localizing an iOS Application in Xcode 6

最后效果最后的效果

把一个iOS应用翻译成不用语言有两个步骤。
一:将所有需要翻译的交互文本、图片等资源从其他的代码故事板等中单独列出来,这步叫做国际化(internationalization (I18N))。
当你国际化完你的APP后,就准备开始本地化它。这步中会导出文本资源交给翻译人员取翻译,等都翻译好了再直接导回Xcode,你的APP支持其他语言了。

1 安装(Setup)

我们将通过一个简单的例子去体会本地化。先创建一个Xcode项目,就用Single View Application模板,项目名字就叫LocalizationExample

下一步就写一点简单的用户界面以供我们进行本地化操作。在Main.storyboard 添加一个UILabel和一个UIImageView,并将label的文本设置成"Hello,World"。然后再下载这几张图片复制到工程目录中(记得选择Copy items if needed),再将其中的en/logo.png设为image view的图片。别忘了给视图加几个约束,不至于运行时消失了。

你还需要知道怎么本地化硬编码(hard-code)字符串,在AppDelegate.m文件中添加一条控制台信息。将下面的语句添加到applicationDidFinishLaunching:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    NSLog(@"Hello, World!");
    return YES;
}

这样我们就有了三个资源需要进行本地化:一张图片,一个label,一段硬编码字符串。
记住开发一个本地化APP大体上和开发一个不进行本地化的APP一样。你可以不管本地化设置视图以及自定义行为,本地化的大部分操作在你完成了基本的功能开发之后进行。

2 国际化(Internationalization)

现在我们有了一个简单的工程,可以开始准备国际化了我们的APP了。这就是我们将国际化资源和其他代码分离的地方,Xcode提供的国际化扩展功能可以让本地化更简单。

第一步 准备故事板

首先,看看我们国际化APP的用户界面。第一步就是在Xcode设置支持的地区,时区。在工程导航栏中点击LocalizationExample,并在推出的的列表的左上方点击工程图标

Localizations块可以添加支持的语言,在我们的例程中,将支持西班牙语(Spanish),点击+并选择Spanish(es),接下来会有一个弹窗让你选择对资源文件进行什么操作。请确保像截图中那样将Main.storyboard和launchScreen.xib的操作都选为Localizable Strings,最后点击完成。


现在Main.storyboard下就有base storyboard和Main.strings两个文件了,前面的就是实际的故事板文件,后面的就是包含了用户交互所需文本的string文件。翻译就是在放在string文件中。


Main.storyboard的国际化就完成了,还差本地化步骤。

第二步 准备硬编码字符串

写在代码中的交互文本需要做特殊处理,而且是必须的,例如,你是用过代码给故事板中的元素设置文本的话。
不过好在国际化硬编码字符串比较简单,只用加上NSLocalisedString宏就可以了,比
如:

     - (BOOL)application:(UIApplication *)application    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
         NSString *greeting = NSLocalizedString(@"Hello, World!", @"A friendly greeting");
        NSLog(@"%@", greeting);
        return YES;
    }

第一个参数是一个key,指向需要翻译的文本,第二个参数可选,作为注释添加到导出的string文件中。一般来讲你可以使用比较抽象的像字典那样的键(比如@"greeting"),不过我觉得直接用需要翻译的文本可读性要好些。

下一步,所有包含NSLocalisedString的地方都会被自动提取并添加到一个有待翻译的string列表中。

3 本地化

一旦APP完成了国际化,就要开始准备本地化了。本地化也是比较简单的,只需导出需要翻译的内容,交给翻译人员去翻译,翻译完再导回来就OK了。程序开发过程中随时可以这样导入导出,不过还是建议在用户界面大部分的功能都确定下来后再去进行。

第一步 导出字符串string

用Xcode导出所有国际化字符串到本地化标准文件.xliff会比较容易。
生成.xliff文件,在工程导航中选择LocalizationExample,在Xcode顶部菜单中选择Editor>Export For Localization...,再指定一个路径,防止冲突,最好选择工程目录外的路径。


点击保存会生成一个包含es.xliff文件的文件夹,打开这个文件就是一些格式化的XML文件,包含了全部需要本地化的字符串。

把这个文件发给翻译,让他们自己打开并翻译。这里,我们自己编辑。
打开es.xliff文件查找Hello,World!,应该可以找到两个单独的<trans-unit>元素,如下

    <trans-unit id="Cns-Fc-27j.text">
    <source>Hello, World!</source>
    <target>Hola, Mundo!</target>
    <note>Class = "IBUILabel"; text = "Hello, World!"; ObjectID = "Cns-Fc-27j";</note>
    </trans-unit>
    <!-- ... -->
    <trans-unit id="Hello, World!">
    <source>Hello, World!</source>
    <target>Hola, Mundo!</target>     <!-- Add a <target> element -->
    <note>A friendly greeting</note>
    </trans-unit>

<note>元素可以看到,第一个是UILabel中的文本,第二个是代码中写了NSLocalizedString的文本

把两条<target>改成Hola,Mundo!,如果没有<target>元素就自己添加一个,现在就可以开始导入了。

第二步 导入

翻译完了.xliff文件,就可以用Xcode导回去了。在工程导航中选择LocalizationExample,在Xcode顶部菜单中选择Editor>Import Localization...,选择已经翻译完的es.xliff文件点击Import。

这样就成功添加西班牙语支持了。打开Main.strings就可以看到翻译了的label文本了,Supporting Files中还有一个新的Localizable.strings文件,其中包含NSLocalizedString的翻译。
待会会测试一下,不过还得再看一下需要国际化的非文本元素。

第三步 本地化图片

本地化字图片和本地化字符串有一点区别,选择logo.png图片在文件检查器(File Inspector)中点击Localize...


之后会有弹窗问这张图片属于哪种语言的本地化文件,Localize...会变成复选框,EnglishSpanish都选中。

这样图片就被本地化了,但还是需要找到这样图片的位置,手动用真正的西班牙语图片替换它。用Finder导航到工程目录,打开LocalizationExample就能看到en.lprojes.lproj文件夹。


这就是本质上一个APP怎么本地化资源了。英语资源都在en.lproj中,西班牙语资源都在es.lproj中,共有部分则在Base.lproj.用教程最开始下的图片中的es/logo.png 替换掉 es/lproj/logo.png。其他的诸如数据,声音,视频等也是同样的本地化方法。

4 测试本地化

一般来讲最好用真机测试本地功能,但是用模拟器也是可以的。通过Xcode的菜单依次选择Producr>Scheme>Edit Scheme...打开scheme编辑器,点击左侧的Run然后点击上方的OptionsApplication Language改成Spanish


以上就是全部的步骤了。下次从模拟器中打开APP就可以看到西班牙语版本的label,图片和控制台输出信息了。

总结

本地化一个iOS APP需要一些额外的工作,不过用Xcode能让过程更加简单明了。通过本教程中,你学到了国际化和本地化的区别,也学到了用Xcode的内建工具本地化字符串的资源的步骤。