作者:ani_di
版权所有,转载务必保留此链接 http://blog.csdn.net/ani_di
MacOS X 国际化学习笔记
资料来源 https://developer.apple.com/cn/internationalization/
国际化会涉及那些修改
- Nib files (windows, views, menus)
- 静态文本
- 图标
- 语音音频
- 在线文档
- 动态文本(日期,时间,数值)
- 计算字数的文本处理部分
- 表格中的排序
多语言的加载顺序
NSBundle会根据当前的语言设置,从bundle directory选择对应的语言包。如果没有,则继续选择第二需求语言,此次类推。如果都没找到,使用开发时的语言。
如何增加多语言bundle
可以手工创建目录,更好的方法是通过xcode。每个资源文件都可以通过Interface builder增加本地化,包括有:
- nib —— nib包含类容比较多。可以是窗口布局、文字、图片,还包括各种IBAction,IBoutlet等
- Images、Sounds —— 可针对单独文件
- Localized text strings —— 所以要显示的文字,都应该放在此文件中。此文件必须是Unicode编码。
- Online help
如何获取当前语言
NSString *identifier = [[NSLocale currentLocale] localeIdentifier]; // 比如Loacl是en_Zh
NSString *displayName = [[NSLocale currentLocale] displayNameForKey:NSLocaleIdentifier value:identifier]; // displayName = “中国”
一般NSBundle会处理好语言的选择。NSBundle会从[NSLocal preferredLanguages]
的列表中寻找,最终找到的语言可以通过[[NSBundle mainBundle] preferredLocalizations]
获取。
创建Localized text strings文件的方法
各个版本XCode创建的方式都不太相同。以XCode 4.3为例,首先向工程中添加strings文件,比如"Localizable.strings"。然后用Interface builer添加多语言。需要翻译的文字以"Key" = "Value";
的形式添加即可。
Localizable text的来源有三种:1. nib文件;2. 源代码;3. 特殊配置
从nib提取文字可以通过ibtool
ibtool --generate-strings-file MainMenu.strings en.lproj/MainMenu.nib
从源代码提取文字也有相应的工具genstrings
find . -name \*.m | xagrs genstrings -o en.lproj/
另一种本地化是Localizing Pathnames。给外部程序使用,比如Finder显示的程序名、目录名字。它们一般是通过特殊文件修改,通用性很强。
代码中使用多语言
我们不会在代码中写多个语言,而只会选用一种语言(开发语言)。但是需要特别的方式做替换,以便让genstrings这类的工具发现。
NSLocalizedString(@"Some Text Key", @"Comment");
// NSLocalizedString是一个宏,而且还有几个变种。它们最终都是通过调用 [NSBundle localizedStringForKey:value:table:] 来实现的
通常 Some Text Key == Some Text,这样方便代码编写和翻译。 Comment也非常重要,填写一些特定的环境信息有利于翻译的准确性和快速定位。
本地化编程
正如上面提到的,本地化过程不仅仅是文字和图片的替换。一些代码也要考虑到本地习惯。
NSString
NSString提供了本地化支持有
- localizedStringWithFormat: – rangeOfString:options:range:locale: – compare:options:range:locale:
- (NSComparisonResult)localizedStandardCompare:(NSString *)string – enumerateSubstringsInRange:options:usingBlock:
NSDataFormatter
- localizedStringFromeDate:dateStyle:timeStyle:
- dateFormatFromTemplate:options:locale:
NSTimeZone
NSDate/NSCalendar/NSDateComponents
日期计算非常复杂
NSNumberFormatter
数字转换特别注意货币。不同地区的货币存在汇率问题。
其它
很多文字的顺序差别很大。格式化字符串可以用n$
指定顺序,例如 %1$@ %2$s
。
// Time.strings - en
"Today is %d/%d/%d" ="Today is %d/%d/%d"; // day/month/year
// Time.string - zh
"Today is %d/%d/%d" ="今天是%3d年%2d月%1d日"; // 年月日