12

我在 Cocoa 中内置的本地化系统遇到了一个奇怪的问题。我使用 genstrings 为我的项目创建了一个 localizable.strings 文件,该文件按预期在我的应用程序中加载和替换字符串。

但是,它似乎只适用于所有其他构建。我将使用 XCode 构建代码,在我的设备上对其进行测试,它会显示正确的字符串,没问题。然而,下一个构建将无法加载字符串文件(至少,这是我的假设。)这不是随机的,而是可以预见的每隔一个构建。我对 Localizable.strings 文件没有做任何花哨的事情。

我什至不知道从哪里开始诊断这个问题,我想知道是否有人有在 Cocoa 上进行本地化的经验。

我在整个代码库中使用 NSLocalizedString,如下所示:

NSLocalizedString(@"ReallyNewGame", @"Are you sure you want to start a new game?")

我的 Localizable.strings 文件中的相应条目:

/* Are you sure you want to start a new game? */
"ReallyNewGame" = "Do you really want to start a new game?";

以下是我的 Info.plist 的相关部分:

<key>CFBundleDevelopmentRegion</key>
<string>English</string>

以下是应用程序的每个其他构建发生的屏幕截图:

正确的: 正确时的外观

不正确: 不正确时的外观

我很困惑为什么会发生这种情况。我没有对 Localizable.strings 文件手动执行任何操作,并且我已经在 XCode 上多次清理了我的项目。任何指向正确方向的指针将不胜感激。如果您需要更多信息,我将尝试提供。

谢谢!

4

7 回答 7

7

我不能给你一个直截了当的答案,但可以建议一些方法来进行。我现在实际上没有多语言应用程序,所以大部分是我通过阅读收集到的(我可能很快就会有一个,所以我对你的问题很感兴趣):

1) Apple 已弃用 English.lproj 的用户,转而支持 en.lproj。在任何情况下,重要的是如果您使用“English”作为 CFBundleDevelopmentRegion 值,则文件夹命名为“English”而不是“en”。

2)您的字符串文件应该是 UTF16,并在文件检查器(Xcode 中最右侧的窗格)中注明

3)有一个很好的previous question有一些图形指针,以确保您的本地化文件在Xcode中正确输入(所以Xcode知道那时,并且知道它必须处理它们)。

4)您的文件可能已损坏,资源指南说您可以在其上运行“plutil -lint Localizable.strings”以验证正确性

5) 作为旁注,许多人指出Mac App Store App是一个很好的实用程序来合并(而不是覆盖)字符串文件(当你添加时)。

6) 如果一切看起来还不错,则在应用首次启动时将以下内容添加到您的 AppDelegate “didFinishLaunchingWithOptions”(在顶部):

NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSLog(@"Strings file: %@", [bundel pathForResource:@"Localizable" ofType:@".strings"]);
NSLog(@"Localizations: %@" [bundle localizations]);
NSLog(@"Local Dict: %@", [bundle localizedInfoDictionary]];
NSLog(@"localizedStringForKey: %@", [bundle localizedStringForKey:@"ReallyNewGame"value:@"WTF???" table:nil];
NSLog(@"Localized String: %@", NSLocalizedString(@"ReallyNewGame", @"Are you sure you want to start a new game?"));
exit(0); // just testing the above for now

多次运行该应用程序。输出应该是一样的。如果它没有对此答案添加评论,我们可以进一步深入研究。如果它是相同的,那么在您的应用程序中进一步导致损坏。

于 2012-07-18T13:54:11.110 回答
6

如果它对其他人有帮助:

我遇到了完全相同的问题:本地化的所有其他构建都不起作用。当我检查包内容时,我发现 en.lproj 中的 Localizable.strings 已损坏 - 该文件本应为 4k,但只有 76 个字节长。下一个版本的腐败消失了,然后又回来了,然后消失了……

原来,当我从另一个项目复制一个文件夹时,我已经将一个额外的 Localizable.strings 文件夹复制到了我的项目中。当我删除额外的 Localizable.strings 文件夹时,一切都神奇地起作用了。哇!

于 2013-05-01T03:41:42.500 回答
3

在以下情况下会出现此问题:

  • 你至少有两个文件 */<locale>.lproj/<table_name>.strings,例如两个文件*/en.lproj/Localizable.strings
  • *.strings您的文件支持不止一种语言

您可能不会创建两个以上.strings同名的文件。当您使用其资源中包含文件的外部库时,通常会发生此问题。您的Localizable.strings资源中可能有Localizable.strings文件- 这是 XCode 无法解决的冲突。

TL; 博士;一般提示:如果您创建一个库以供其他开发人员用作第三方代码,而不是创建Localizable.strings文件并NSLocalizedString()在其中使用,创建自定义命名的可本地化字符串表(例如MyLibName.strings)并使用NSLocalizedStringFromTable.

问题示例及详细描述:

我创建了一个“问题演示”存储库:https ://github.com/kajot/LocalizedStringsMergingFailure

特别是每隔一次运行失败的测试:https ://github.com/kajot/LocalizedStringsMergingFailure/blob/master/LocalizedStringsMergingFailureTests/LocalizedStringsMergingFailureTests.m

│  ├── KJAppDelegate.h
│   ├── KJAppDelegate.m
│   ├── Localizations1
│   │   ├── de.lproj
│   │   │   └── Localizable.strings
│   │   └── en.lproj
│   │       └── Localizable.strings
│   ├── Localizations2
│   │   ├── de.lproj
│   │   │   └── Localizable.strings
│   │   └── en.lproj
│   │       └── Localizable.strings

每次OTHER构建,XCode 都会Localizable.strings在包中创建一个损坏的文件。解决方案:不要为同一个目标创建/添加多个LocalizedString同名表。

LocalizedStringtable 是一组*/<locale>.lproj/<tableName>.strings文件。在上面的示例中,有两个表,每个都命名Localizable(表的默认名称)。

如果调用了一个表Localizable,您可以通过使用从表中获取本地化字符串

`NSLocalizedString(key, optionalComment)`.

解决方案:

您可以合并这两个表(将对应的文件与相同语言的翻译连接起来)或更改其中一个表的名称。

第二种方法的示例(更改其中一个表的名称):

│  ├── KJAppDelegate.h
│   ├── KJAppDelegate.m
│   ├── Localizations1
│   │   ├── de.lproj
│   │   │   └── Localizable.strings
│   │   └── en.lproj
│   │       └── Localizable.strings
│   ├── Localizations2
│   │   ├── de.lproj
│   │   │   └── NewTableName.strings
│   │   └── en.lproj
│   │       └── NewTableName.strings

现在,您可以通过使用从新表 ( NewTableName) 中获取翻译,使用.NSLocalizedStringFromTable(key, @"NewTableName", optionalComment) 从“原始”表 ( Localizable) 中获取翻译NSLocalizedString(key, optionalComment)

于 2014-08-13T22:12:05.480 回答
0

其他线程可能会有所帮助...一个iOS应用程序中的多个Localizable.strings文件

再次,也许你可以清理然后从 xcode 构建应用程序......

于 2012-07-14T06:03:24.807 回答
0

关于我的应用程序图标,我遇到了类似的问题。我的应用程序中有几个目标,并且都有不同的应用程序图标。由于某种原因,其中一个应用程序图标已损坏,因此我的所有目标都通过其他目标的应用程序图标切换。这很奇怪,因为一个目标不应该知道其他目标 app-icon,如果它不用于两个目标并在 xcode 中标记为两个目标。

我通过删除损坏的 png 并将其重新添加到项目中解决了这个问题。如果您使用 i18n 文件执行此操作,它也可能会有所帮助。但可以肯定的是,不仅要从 xcode 中删除引用,还要删除整个文件。最好是在一些外部编辑器(如 textwrangler)中打开文件,然后将文本复制到新文件中,然后改用它。

祝你好运。

于 2012-07-18T15:47:47.173 回答
0

你所经历的行为是完全正常的。为什么?


如果您检查这些行,原始宏定义的相关部分NSLocalizedString

#define NSLocalizedString(key, comment) \
        [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]

您可以看到该comment参数是欺骗性参数,它从未使用过。(仅供阅读代码的开发人员使用)


此外,如果您查看NSBundle类 Reference,您可以阅读以下有关方法返回值的有趣内容-localizedStringForKey:value:table:

返回值

如果 value 是 nil 或空字符串,并且在表中未找到本地化字符串,则返回key

这就是您取回密钥的原因,因为您的文件中可能没有此密钥的价值。Localizable.string

不幸的消息,但这是正常的。


解决方案如下:

NSLocalizedString(@"Are you sure you want to start a new game?", @"");

并在您的Localizable.string文件中:

@"Are you sure you want to start a new game?" = "Do you really want to start a new game?";
于 2012-07-18T16:06:25.760 回答
0

我刚刚发现了一些让我死去的东西!我有同样的问题:取决于 STRINGS 文件,有时它可以工作,有时不能/

我发现,如果 .strings 文件中的某些行以双分号结尾

;;

下面的所有行都被忽略了!

例如: 这很好用:如您所见, NSLocalizationString 命令正确替换了模板中的字符串

现在,注意双分号

上图效果很好:如您所见, NSLocalizationString 命令正确替换了模板中的字符串 但另一张图显示,在双分号之前,它将忽略所有内容。这是一团糟!没有资源编译错误,什么都没有。简直是噩梦!

希望它可以帮助人们不要失眠!

于 2019-12-16T21:28:11.493 回答