【问题标题】:NSLocalizedString only retrieves the key, not the value in Localizable.strings (IOS)NSLocalizedString 只检索键,而不是 Localizable.strings (IOS) 中的值
【发布时间】:2012-03-04 07:16:51
【问题描述】:

我制作了一个名为“Localizable.strings”的字符串文件,并向其中添加了两种语言,如下所示:

"CONNECTIONERROR" = "Check that you have a working internet connection.";
"CONNECTIONERRORTITLE" = "Network error";

我还将文件转换为 Unicode UTF-8 但是,当我像这样创建 UIAlertView 时:

 UIAlertView *myAlert = [[UIAlertView alloc]
 initWithTitle:NSLocalizedString(@"CONNECTIONERRORITLE",nil)
 message:NSLocalizedString(@"CONNECTIONERROR",nil)                    
 delegate:self
 cancelButtonTitle:@"Ok"
 otherButtonTitles:nil];

警报视图仅显示键文本,而不显示值。例如,如果我将 UITextviews 文本设置为 NSLocalizedString(@"CONNECTIONERROR",nil),它会起作用,但警报视图仅显示密钥。有谁知道怎么回事?

【问题讨论】:

  • NSLocalizedString() 如果找不到键/值对,则返回键。
  • 对不起,我没有复制/粘贴代码,所以它是一个类型-o。然而,我的应用程序中的代码是正确的。
  • 发现问题。它在 iPhone 模拟器中对我不起作用,所以我在实际设备上对其进行了测试,它确实有效。
  • 看看这个How to Answer[1],它可能会有所帮助。 [1]:stackoverflow.com/a/8972349
  • 不要害怕在键中使用下划线或空格。

标签: ios xcode uialertview nslocalizedstring localizable.strings


【解决方案1】:

当运行时无论出于何种原因找不到指定的键时,就会发生这种情况。在您的情况下,这很可能是由于拼写错误:CONNECTIONERRORITLE 缺少 TTITLE。还要注意编译Localizable.strings文件时的任何警告/错误:如果有不平衡的"或缺少;,则无法正确编译/读取文件。

【讨论】:

    【解决方案2】:

    NSLocalizedString 用法意味着您需要精确的大小写和拼写才能从中获取内容。你会注意到这个说

    NSLocalizedString(@"CONNECTIONERRORITLE",nil)
    

    应该是什么时候

    NSLocalizedString(@"CONNECTIONERRORTITLE",nil)
    

    如果您查看第一部分的最后一部分,它会显示“ITLE”,而不是“TITLE”

    【讨论】:

    • 我们最近在过渡到更新的 Swift 期间将枚举的名称更改为以小写开头。但是我们忘记了我们从枚举名称中派生了一些长字符串键。名字不再匹配。一个不同的角色在中间,所以很难注意到。我正在使用 Xcode 的“查找”功能检查字符串匹配。由于它不区分大小写,因此它找到了键并且我认为它们匹配。您在这里的回答让我仔细检查并找到错误。谢谢。 (现在我们的默认值会改变,所以我们会在调试版本中立即注意到。)
    【解决方案3】:

    在实际设备上测试了该应用程序,它工作正常

    【讨论】:

    • 另一个问题是 Localizable.strings 文件没有被正确地清理和重新初始化;如果您之前在设备上进行测试,然后创建或显着更改了 Localizable.strings 文件,则并不总是注意到更改,因此您必须在更改正确传播之前清理您的构建并从设备中删除副本。
    • 从模拟器中卸载应用程序对我有用。
    • 我发现从 Mac 上的 Build Products 文件夹中删除应用程序足以让 Xcode 使用所有最新文件。
    【解决方案4】:

    在我的情况下,这是因为我错误地将文件命名为“Localization.strings”并且没有注意到(它必须命名为 Localizable.strings)。如前所述,症状是因为编译器找不到字符串。否则,原因可能有很多,但通常是缺少分号或引号。当您同时进行大量本地化时,很难找到这些。吸取的教训是在开发过程的早期开始构建本地化文件,并在开发过程中构建它,以便更容易发现它们。

    【讨论】:

    • 谢谢,这条评论对我帮助很大!
    • 大声笑,这有帮助。谢谢
    • 请注意文件名区分大小写。所以你必须使用“.strings”而不是“.Strings”
    • 谢谢,这节省了我的时间
    • 文件名应该是Localizable.string,上面有L,没有s...约定过度配置...我讨厌这种范式。
    【解决方案5】:

    我在 iOS 模拟器上遇到了这个问题。我最终删除了模拟器目录中的 Localization.strings 文件

    ( /Users/(me)/Library/Application Support/iPhone Simulator/5.0/Applications/(etc)/(project)/(application.app)

    cd 到那里并删除在那里找到的所有 Localization.strings 副本。

    由于某种原因,构建干净、退出 iOS 模拟器、退出 XCode 等通常的橡胶鸡巫术不起作用,但确实如此。至少对我来说,今天。

    【讨论】:

      【解决方案6】:

      要确定是否找到了 Localizable.strings 文件,请检查 .app 构建的内容,您也可以在代码中执行此操作:

      //en 是英文的,所以在这里指定你的 NSString *path = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"];

      如果路径为NULL,则表示文件未找到。

      【讨论】:

        【解决方案7】:

        如果你在行尾写了双分号,NSLocalization 不起作用。 你应该检查 Localizable.strings 文件是否有 ';;'

        【讨论】:

        • 是的,发生在我身上,我检查并解决了这个问题......谢谢你的帮助。
        【解决方案8】:

        本地化文件的第一行必须包含映射,否则 SDK 不会读取该文件。

        【讨论】:

          【解决方案9】:

          放一个;在 Localizable.strings 文件的行尾。

          【讨论】:

            【解决方案10】:

            同样的问题,使用文件名解决:Localizable.strings

            【讨论】:

              【解决方案11】:

              将 InfoPlist.strings 文件重命名为 Localizable.strings(双击),然后您将获得该键的正确字符串。

              【讨论】:

                【解决方案12】:

                仔细检查Localizable.strings 文件是否被添加到

                目标 -> 构建阶段 -> 复制捆绑资源

                它不是为我自动添加的。

                Edit 2021:使用 XCode 12 必须将 Localizable.strings 添加到

                目标 -> 构建阶段 -> 编译资源

                【讨论】:

                • 你是救世主。这就是我的问题。
                • 从 Copy Bundle Resources 中删除它并重新添加后,它对我有用。
                • 太棒了!非常有帮助!我更新了答案,因为菜单与原始答案相比略有变化,我认为这仍然可以帮助很多人。
                【解决方案13】:

                重置模拟器设置对我有用。

                iOS 模拟器 > 重置内容和设置...

                【讨论】:

                  【解决方案14】:

                  请务必不要将“@”放在您的 keyvalue 前面,如下所示:

                  @"key" = @"value";
                  

                  应该只是:

                  "key" = "value";
                  

                  “@”仅在访问时放在键的前面:

                  NSWebLocalizedString(@"key", @"label for coder");
                  

                  【讨论】:

                    【解决方案15】:

                    就我而言,我尝试清理项目并删除派生数据仍然无效。我删除了字符串文件中的几个换行符,然后 Xcode 再次找到这些字符串。

                    【讨论】:

                      【解决方案16】:

                      您是否尝试过清理和重建项目?

                      【讨论】:

                        【解决方案17】:

                        将文件名更改为 Localizable.strings,确保文件检查器中的目标已设置。 为避免语法错误,右键单击 Localizable.strings 文件->打开为->ASCII 属性列表 此外,清理项目并重新构建对我来说也有帮助。

                        【讨论】:

                        • 这也是在 Localizable.strings 文件中查找错误的好方法。
                        【解决方案18】:

                        当突然本地化停止翻译字符串时,我一切正常。这意味着 Xcode 无法读取该文件。

                        这发生在我身上,因为我在 Localized.strings 文件中粘贴了一个错误字符。当我删除带有违规字符(非 Unicode 字符?错误的引号?无法判断)的几行时,一切恢复正常。

                        为了找到有问题的行,我设置了一个断点,并在调试器中手动翻译了我文件中的字符串,直到遇到第一个无法翻译的行。

                        【讨论】:

                          【解决方案19】:

                          我已经搜索了 5 个小时的解决方案,我尽我所能让我的应用本地化工作。

                          问题是我项目的一个 Pod 有一个 Localizable.strings 文件(实际上是 Parse pod 没有重命名它)。因此,我的应用程序无法识别我的 Localizable.strings 文件。

                          我通过将文件名更改为“MyappnameLocalizable.strings”并以这种方式使用 NSLocalizedString 来解决此问题:

                                  NSLocalizedString("key", tableName: "MyappnameLocalizable", comment: "comment")
                          

                          【讨论】:

                            【解决方案20】:

                            建议的解决方案都不适合我,但我确实通过删除 Products 中的 .app 文件解决了这个问题

                            【讨论】:

                              【解决方案21】:

                              如果您的字符串文件中有任何多余的分号,它不会本地化。

                              【讨论】:

                                【解决方案22】:

                                我遇到了类似的问题,突然我的可本地化字符串根本不起作用。然后我使用文件比较与旧的 .strings 副本,最后我发现我不小心删除了其中的一个键。

                                因此,如果格式错误,Xcode 绝对不会为您读取字符串。

                                这是它所期望的格式 "Key" = "Value";

                                【讨论】:

                                  【解决方案23】:

                                  将您的 .strings 文件名更改为 Localizable.strings,它对我有用。

                                  【讨论】:

                                    【解决方案24】:

                                    对于 xcode 9.2,使用控制台从项目的模拟器中删除“Localizable.strings”文件为我解决了这个问题。这是像我这样的懒人的命令;)

                                    不要忘记将 YOUR_APP_NAME_HERE 替换为您的项目名称

                                    Shell 脚本:

                                    cd
                                    cd Library/Developer/CoreSimulator/Devices/
                                    find . -name "Localizable.strings" | grep "YOUR_APP_NAME_HERE.app" | xargs rm
                                    

                                    如果您在使用单元测试时遇到问题,它将在模拟器中运行;)

                                    【讨论】:

                                      【解决方案25】:

                                      斯威夫特 4:

                                      如果您使用多个捆绑包,例如在外部框架中使用它:

                                      var currentBundle = Bundle.main
                                      NSLocalizedString("CONNECTIONERRORITLE", tableName: nil, bundle: currentBundle, value: "", comment: "")
                                      

                                      【讨论】:

                                        【解决方案26】:

                                        在开发 SDK 时。你需要一些额外的操作。

                                        1) 像往常一样在 YourLocalizeDemoSDK 中创建 Localizable.strings

                                        2) 在 YourLocalizeDemo 中创建相同的 Localizable.strings

                                        3) 找到 YourLocalizeDemoSDK 的Bundle Path

                                        Swift4

                                        // if you use NSLocalizeString in NSObject, you can use it like this
                                        let value = NSLocalizedString("key", tableName: nil, bundle: Bundle(for: type(of: self)), value: "", comment: "")
                                        

                                        Bundle(for: type(of: self)) 帮助您在 YourLocalizeDemoSDK 中找到捆绑包。如果你改用Bundle.main,你会得到一个错误的值(实际上它与键是同一个字符串)。

                                        但是如果你想使用dr OX提到的String扩展。你需要做更多。源扩展名如下所示。

                                        extension String {
                                            var localized: String {
                                                return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
                                            }
                                        }
                                        

                                        我们知道,我们正在开发一个 SDK,Bundle.main 将获得 YourLocalizeDemo 的捆绑包。这不是我们想要的。我们需要 YourLocalizeDemoSDK 中的捆绑包。这是一个快速找到它的技巧。

                                        在 YourLocalizeDemoSDK 的 NSObject 实例中运行以下代码。你会得到YourLocalizeDemoSDK的URL。

                                        let bundleURLOfSDK = Bundle(for: type(of: self)).bundleURL
                                        let mainBundleURL = Bundle.main.bundleURL
                                        

                                        将这两个url都打印出来,你会发现我们可以在mainBundleURL的基础上构建bundleURLofSDK。在这种情况下,它将是:

                                        let bundle = Bundle(url: Bundle.main.bundleURL.appendingPathComponent("Frameworks").appendingPathComponent("YourLocalizeDemoSDK.framework")) ?? Bundle.main
                                        

                                        字符串扩展名将是:

                                        extension String {
                                            var localized: String {
                                                let bundle = Bundle(url: Bundle.main.bundleURL.appendingPathComponent("Frameworks").appendingPathComponent("YourLocalizeDemoSDK.framework")) ?? Bundle.main
                                                return NSLocalizedString(self, tableName: nil, bundle: bundle, value: "", comment: "")
                                            }
                                        }
                                        

                                        希望对你有帮助。

                                        【讨论】:

                                          【解决方案27】:

                                          我用这种方法解决了。

                                          localize 文件是用名称 main.Strings 创建的。然后,我打开 main.Strings 文件(针对添加的每种语言),并手动将它们重命名为 localize.strings 并将它们一一添加到我的项目中,同时我删除了 main.strings

                                          要评估的第二件事是:检查。您的文件,所有keys 必须以; 结尾,并确保所有quotes 都正确打开和关闭。

                                          您可以在 swift 4 中使用:

                                          myButon.setTitle(NSLocalizedString("forgotpassword.key", comment: ""), for: UIControlState.normal)
                                          

                                          【讨论】:

                                            【解决方案28】:

                                            因为我在寻找类似问题的答案时偶然发现了这一点,所以我将解决方案留在这里:

                                            如果您的密钥中包含“\u2028”而不是“\n”,它将始终只返回密钥而不是值。似乎是本地化的错误。

                                            【讨论】:

                                            • 在我看来,\u2028 和 \n 都不适用于本地化。无论如何,我给了你一个 +1 以承认自 xCode 9.2 以来一直不稳定的本地化缺陷。
                                            【解决方案29】:

                                            当一种语言正常工作而另一种语言有一半时间工作而其他时间我得到密钥而不是该密钥的本地化版本时,我遇到了问题。

                                            在我的情况下,问题是在手动合并版本控制冲突后,留下了额外的 '>>>>>' 行,项目没有抱怨(不像你错过分号时,它抱怨)并且正在构建正确地,因此“>>>>>”之前的每个键都被翻译,而之后的每个键都没有。

                                            如果更简单的解决方案失败,您可能必须遍历每一行并寻找额外的字符(不仅是“>>>>>”,还有其他额外的字符),或者如果您使用的版本控制变旧,稳定版本的 Localizable.strings 文件并手动完成更改并添加以后的提交。

                                            【讨论】:

                                            • 谢谢。在我的情况下,它是我在合并过程中意外添加的 Localizable.string 文件中的一个键之前的一个加号字符“+”
                                            【解决方案30】:

                                            我们正在处理一个问题,其中一些键没有获得它们的值,尽管它们都存在于 Localizable.strings 中。

                                            原来构建文件的开发者在一行中添加了两个分号,导致该文件的解析非常不稳定。

                                            在我找到两个分号并排放置并删除其中一个后,应用程序将无法再编译。在这一点上,我能够找到一些没有分号的行。修复这些并编译应用程序后,我所有的字符串都可以正常工作。

                                            因此,在同一行中有两个分号会导致文件编译,尽管它在其他行中缺少分号。

                                            看起来 Apple 的 .strings 文件解析器非常原始。

                                            不幸的是,plist linter 在我们的例子中没有用。为了找到并解决问题,我复制并粘贴了 Localizable.strings 文件的全部内容(超过 2000 行长),然后开始将其复制回 20 行块并每次编译。这是找到 linter 无法捕获的问题的唯一方法。

                                            【讨论】:

                                            • 我在分号后的行尾有一个反引号 - 其中一个:`,基本上看起来就像屏幕上的一粒灰尘。在查找方面——也可以使用二分搜索——首先,我将主屏幕中使用的字符串的字符串定义放在文件的第一行,然后在中间点,然后继续将剩余距离分成两半取决于字符串是正确输出还是仅作为键输出。
                                            猜你喜欢
                                            • 2020-08-23
                                            • 1970-01-01
                                            • 1970-01-01
                                            • 2019-02-18
                                            • 1970-01-01
                                            • 1970-01-01
                                            • 1970-01-01
                                            • 1970-01-01
                                            • 2016-10-21
                                            相关资源
                                            最近更新 更多