iOS 对国际化的支持是相对比较完善的。
应用的国际化支持
在 Project 属性中,有 Localizations 一项,在其中可以管理支持的语言列表,还可以选择是否开启 Base 语言。
为资源文件开启国际化
在资源文件(如 strings/xib/storyboard)的文件属性中,可以在 Localization 项中进行国际化语言的管理。如果尚未国际化,会有一个长长的 Localization 按钮,点击后开启这个文件的国际化。如果已国际化,会显示并可管理当前文件已支持的语言。
如果想取消对这个文件的国际化,在 Xcode 里做不到。唯一的办法是,去 Finder 里把各个语言的 .lproj 目录下的这个资源文件删掉,只留一份放到工程目录的最外层(而不从属与任何 .lproj 目录)。
字符串的国际化:
自己新建一个 String 文件到工程里,名为 Localizable.strings
即可。(这是默认的文件名,调用 NSLocalizedString
方法默认取这个文件,如果用了其他的文件名,则每次调用方法时,需要指定文件名)
例如,Localizable.strings 内容为:
Localizable.strings(Chinese (Simplified))1 2 3 4 5
| "Today" = "今天"; "Yesterday" = "昨天"; "%d days ago" = "%d天前"; /* {User First Name}'s Profile */ "%@'s Profile"="%@'s Profile";
|
Localizable.strings(English)1 2 3 4 5
| "Today" = "Today"; "Yesterday" = "Yesterday"; "%d days ago" = "%d days ago"; /* {User First Name}'s Profile */ "%@'s Profile"="%@的个人资料";
|
获取时:
1 2 3 4 5
| NSString *str; str = NSLocalizedString(@"Today", nil); int temp = 3; str = [NSString stringWithFormat:NSLocalizedString(@"%d days ago", nil), temp]; str = [NSString stringWithFormat:NSLocalizedString(@"%@'s Profile", @"{User First Name}'s Profile"), user.name];
|
上面是常用的情况。还有一种复杂的情况,是在有些语言里,某两个参数的位置可能会颠倒,这时需要使用转义符:
1
| "%@ Error! %@ failed!" = "%2$@ 失败了!%1$@ 错误了!";
|
更为详细的可参照:
http://nshipster.com/nslocalizedstring/
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/LoadingResources/Strings/Strings.html
https://developer.apple.com/library/ios/documentation/MacOSX/Conceptual/BPInternational/InternationalizingYourCode/InternationalizingYourCode.html
xib/storyboard 的国际化
除了借助 localizable strings 文件进行界面国际化之外,对于 xib/storyboard 可以直接进行国际化。虽然看上去很方便、很直观,但其实并不是特别好用。
它的原理其实还是 localizable strings,只不过这个 strings 文件是 Xcode 自动创建的。创建的时机是在你对这个界面开启 localization 时,而且它并不会监控 xib/storyboard 的变化。如果你在 localization 之后又改变了这个 xib/storyboard,主要是增加了新的控件,那么这个新控件并不会自动出现在 strings 文件中。
那你就没办法了,Xcode 也没有提供同步的手段,你唯一能做的是查看 xib 的源代码,从中找到新建控件的 ID,然后自己写到那个 strings 文件里--噢,这一点都不方便。
Bundle Display Name 的国际化
显然,需要对不同语言设定不同的应用名称,也就是 Bundle Display Name,我们都知道它在 Info.plist 里。
但注意,不是把 Info.plist 进行 Localization,如果对 Info.plist 进行了 Localization,会编译报错 the file Info.plist does not exist.
正确的方式是在工程里新建一个名为 InfoPlist.strings
的文件,然后对这个 strings 文件进行国际化,在里面写入:
1
| "CFBundleDisplayName" = "名称";
|
即可。
注意,需要把 InfoPlist.strings 文件加到工程属性里的 Copy Bundle Resources 里(默认应该就给加上了,如果有问题可以检查一下)。但不要把 Info.plist 文件加到 Copy Bundle Resources 里,否则出现编译警告。
Base 语言的问题
测试发现,将 iOS 设备设置为并没有支持的语言时,应用并没有正确地显示为 Base 中的字符串(英语),而是显示成了简体中文。
Stackoverflow 上有很多国内外开发者遇到了这个问题,但都未找到原因和解决方法。
http://stackoverflow.com/questions/20241256/ios-app-default-language-en-is-not-applied
http://stackoverflow.com/questions/20584984/ios-set-a-default-language-in-xcode-for-my-app
http://stackoverflow.com/questions/18114994/does-my-base-internationalization-storyboard-have-to-correspond-to-a-fallback-la
App Store 应用名称及简介的国际化
希望让应用在不同国家的 App Store 中显示不同语言的名称,在 iTunes Connect 里新建应用时先用一个主要语言新建,如简体中文,新建成功后在 App 信息里可以看到“可本地化的信息”,可以在右侧选择语言,并且填入相对应的信息。另外,在版本中对应用简介、关键字、截图等也都须进行国际化。
如果未做本地化,则按照选择的主要语言显示。