Jas*_*son 34 iphone localization internationalization localizable.strings ios
在我当前的应用程序中,我有显示消息的代码,例如"5个已处理的项目".为了保持短语在语法上正确,即它是否应该是"5 Item"或"5 Items",我使用以下代码:
int numItems = 5;
NSString *myString = [[NSString alloc] initWithFormat:@"%d Item%@ Processed", numItems, (numItems == 1 ? @"" : @"s")];
Run Code Online (Sandbox Code Playgroud)
这个现在工作正常.但我正在本地化我的应用程序,并希望确保我正在翻译应用程序的所有语言中的文本语法正确.我可以这样做:
int numItems = 5;
NSString *myString = (numItems == 1 ?
NSLocalizedStringWithTable(@"%d Item Processed", @"myApp", @"singular version") :
NSLocalizedStringWithTable(@"%d Items Processed", @"myApp", @"plural version"));
Run Code Online (Sandbox Code Playgroud)
但是,并非所有语言都具有相同的复数操作规则!例如,(原谅我在这里非常具体的例子)俄语中,用最后一个数字1结尾的数字修改的名词(即21,31,但不是 11)采用主格,结束于2-4的数字采用了genitive奇异,5+采取属性复数的情况.这将需要更严格的逻辑来处理如何以语法正确的方式复数特定名词,并且该逻辑与英语逻辑不匹配.因此,从理论上讲,我不能在Objective-C代码中使用语法逻辑,而应该在strings文件中使用语法逻辑.有没有办法做到这一点?人们如何为他们的应用翻译动态文本,以使其在语法上保持正确?
小智 61
从iOS 7开始,Foundation框架本身就支持多元化. 这是一个如何使用它的快速教程:
创建一个名为Localizable.stringsdict的plist文件
英文本地化:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>%d tasks waiting for action</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@tasks@ waiting for action</string>
<key>tasks</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>A task is</string>
<key>two</key>
<string>Two tasks are</string>
<key>other</key>
<string>%d tasks are</string>
</dict>
</dict>
</dict>
</plist>
Run Code Online (Sandbox Code Playgroud)
波兰语本地化:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>%d tasks waiting for action</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>Masz %#@zadanie@ do zrobienia</string>
<key>zadanie</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>jedno zadanie</string>
<key>few</key>
<string>%d zadania</string>
<key>other</key>
<string>%d zada?</string>
</dict>
</dict>
</dict>
</plist>
Run Code Online (Sandbox Code Playgroud)
最后在您的实现文件中,您可以像这样调用字典:
cell.tasksInfoLabel.text = [NSString localizedStringWithFormat:NSLocalizedString(@"%d tasks waiting for action", @"%d tasks waiting for action"), (long)taskCount];
Run Code Online (Sandbox Code Playgroud)
编辑:感谢Zaphod指出这一点 - >:您还需要在.stringsdict旁边创建Localizable.strings文件以使复数工作(即使它是空的).
小智 12
我的团队开发了一个开源库来处理这种情况,在github上查看我们的iOS i18n复数库.
基本前提是根据CLDR复数规则扩展多个字符串的键以包含它们的复数形式,并且字符串的查找不使用典型的NSLocalizedString.
发布的示例的英文文件如下所示:
"%d Items Processed##{one}" = "1 Item Processed";
"%d Items Processed##{other}" = "%d Items Processed";
Run Code Online (Sandbox Code Playgroud)
然后使用SLPluralizedString函数完成查找
SLPluralizedString(@”%d Items Processed”, numItems, @”Number of items processed”);
Run Code Online (Sandbox Code Playgroud)
在运行时,对于英语,将返回字符串"1 Item Processed"或"%d Items Processed",具体取决于numItems的值.
俄语文件将如下所示:
"%d Items Processed##{one}" = "%d ??????? ?????????";
"%d Items Processed##{few}" = "%d ???????? ??????????";
"%d Items Processed##{many}" = "%d ????????? ??????????";
"%d Items Processed##{other}" = "%d ???????? ??????????";
Run Code Online (Sandbox Code Playgroud)
然后,您的代码将查找"已处理的项目"(对于俄语或任何其他语言)不必更改,并且库将根据该特定语言的CLDR复数规则返回正确的字符串.
请随时与您分享您对图书馆,建议,改进等的看法.