文本信息本地化在本地化工作中占有很大的比例。包括了:应用名称本地化、系统按钮和信息本地化,以及静态文本信息本地化。
系统按钮和信息本地化
还记得天气预报应用背后的“完成”按钮吗,它在中文环境下是“完成”,在英语环境下是“done”。
还有一些系统给我们的提示信息,连接蓝牙设备时的系统提示。它在中文环境下是中文提示,在英语环境下是英文提示。
系统按钮上的文本和系统提示信息的文字我们都是不能修改的,但是如果我们不进行本地化的设置,即便是这些基本信息也一直都是英文显示。我们可以尝试在故事板中创建画面,在导航栏中放置两个系统按钮done和edit。然后分别在英文和中文环境下运行看看是否有变化。
事实上,它们一直都没有变化,这是什么原因?原因在于我们没有对工程本进行地化设置,打开工程中的project选择l10n,点击localizations下面“+”,弹出菜单选择“chinese(zh-hans)”,这样就添加了简体中文本地化文件。
这样我们的工程就同时支持中文和英文的本地化了,系统按钮和提示信息等也都已经实现本地化了,这个过程不需要编写代码。
应用名称本地化
应用程序名称本地化是一个很重要的问题,左图是中文语言环境下的ipod touch桌面,右图是英文语言环境下的ipod touch桌面。我们会看到日历、地图、股市等几个应用名称都有本地化。
我们要编写一个应用它的英文名是:“localization”,中文名是:“本地化”。打开工程l10n应用,找到工程中的l10n-info.plist文件,该文件是工程属性文件,应用程序名称就是在这个文件中定义的,但是我们不能在这里本地化,要想本地化必须借助于另一个文件infoplist.strings,infoplist.strings是可以本地化的。在上一节系统按钮和信息本地化后,infoplist.strings下面会有两个文件:infoplist.strings(english)和infoplist.strings(chinese)。打开finder看到en.lproj和zh-hans.lproj,它们的目录结构如下:
├── en.lproj
│ ├── infoplist.strings
│ └── mainstoryboard.storyboard
└── zh-hans.lproj
├── infoplist.strings
└── mainstoryboard.storyboard
cfbundledisplayname和cfbundlename的键能够配置应用名字,cfbundledisplayname键配置应用显示的名字。cfbundlename配置应用短名字,不超过16字符,显示菜单栏和应用窗口信息中。
infoplist.strings(chinese)文件的内容如下:
cfbundledisplayname="本地化";
cfbundlename="本地化";
infoplist.strings(english)文件的内容如下:
cfbundledisplayname="localization";
cfbundlename="l10n";
运行结果,图标下文字显示的是cfbundledisplayname键配置的名字。
程序代码输出的静态文本本地化
应用中的静态文本都应该实现本地化,但是它们可能是通过程序代码输出,也可能是通过ib在nib或故事板设计输出的。采用“tabbed application”工程模板创建的标签应用程序,它的两个标签上的标题first和second,以及画面中的文字都属于静态文本。
同样都是这个工程如果在创建过程中分别创建基于故事板和nib技术的两个版本,故事板版本的两个标签上的标题是通过ib在编写在故事板文件中的(关于故事板和nib中静态文本的本地化我们会在下一节介绍)。但在nib版本中两个标签上的标题通过程序代码输出的。firstviewcontroller.m中的构造方法:
- (id)initwithnibname:(nsstring *)nibnameornil bundle:(nsbundle *)nibbundleornil
{
self = [super initwithnibname:nibnameornil bundle:nibbundleornil];
if (self) {
self.title = nslocalizedstring(@"first", @"first");
self.tabbaritem.image = [uiimage imagenamed:@"first"];
}
return self;
}
secondviewcontroller.m中的构造方法:
self.title = nslocalizedstring(@"second", @"second");
self.tabbaritem.image = [uiimage imagenamed:@"second"];
在这个两个构造方法中设置标题属性的时候使用了nslocalizedstring宏,nslocalizedstring宏本质上是调用nsbundle的localizedstringforkey:value:table:方法,nslocalizedstring是从默认字符串资源文件(localizable.strings)中取出本地化的字符串。
字符串资源文件默认命名为localizable.strings,文件采用utf-16编码。如果静态文本不是很多可以自己创建localizable.strings文件。选择“supporting files”组,打开菜单file→new→file…,选择ios→resource→string file,输入文件名“localizable.strings”。
选择文件localizable.strings打开文件显示检查器,点击localization中的“make localized”按钮,这可以帮助我们创建本地化的localizable.strings文件。
点击“make localized”按钮弹出一个选择本地化语言的对话框。我们可以选择english,然后点击localize按钮。
然后再按照事实上,添加简体中文本地化文件
英文版中localizable.strings文件中添加内容:
/* first */
"first" = "first";
/* second */
"second" = "second";
中文版中localizable.strings文件中添加内容:
"first" = "第一";
"second" = "第二";
使用genstring工具
但是有的时候字符串很多,提取和编写起来很麻烦,此时我们可以借助于命令行工具genstring,从m或mm文件中扫描下面宏,并取出字符串输出到本地化文件中。
cfcopylocalizedstring
cfcopylocalizedstringfromtable
cfcopylocalizedstringfromtableinbundle
cfcopylocalizedstringwithdefaultvalue
nslocalizedstring
nslocalizedstringfromtable
nslocalizedstringfromtableinbundle
nslocalizedstringwithdefaultvalue
cf开头宏和ns开头宏两两对应,ns开头宏是foundation 框架是基于objective-c语言的,cf开头宏是core foundation 框架是基于c语言的。nslocalizedstringfromtable和nslocalizedstringfromtableinbundle函数是在自定义字符串资源文件名时使用。
下面是genstrings命名的基本语法:
genstrings [-a] [-q] [-o <outputdir>] sourcefile
其中参数:
-a 在存在的文件后面追加内容
-q 关闭多个键/值对的警告
-o 指定输出目录
因此如果我们想输出到en.lproj目录,则代码如下:
genstrings -o en.lproj *.m
这样就在en.lproj目录下面产生了localizable.strings文件,需要注意的是上面的命令每次运行的时候都会覆盖localizable.strings文件,如果内容不想覆盖可以使用-a参数,然后在文件中进行修改。