String(localized:) 没有单独的键和值?

mat*_*att 7 localization ios swift ios15

iOS 15 中的新功能邀请我们使用此 String 初始化方法在 Swift 代码中创建可本地化的字符串:

\n
init(localized keyAndValue: String.LocalizationValue, \n    table: String? = nil, bundle: Bundle? = nil, \n    locale: Locale = .current, comment: StaticString? = nil)\n
Run Code Online (Sandbox Code Playgroud)\n

问题在于,正如内部名称所示,第一个参数既用于键又用于值。您可以从这个本地化的法语字符串文件中看到:

\n
/* Alert message: Report a tap */\n"You tapped me!" = "Vous m'avez tap\xc3\xa9!";\n
Run Code Online (Sandbox Code Playgroud)\n

这是我说的结果

\n
String(localized:"You tapped me!", comment: "Alert message: Report a tap")\n
Run Code Online (Sandbox Code Playgroud)\n

并本地化为法语。

\n

那是完全错误的!这应该是键\xe2\x80\x93值对的列表;我们不应该使用面向用户的英文文本作为key

\n

一方面,如果我们现在更改String(localized:comment:)通话中的英文文本,我们的法语翻译就会中断。此外,我们无法为不同上下文中使用的相同英文文本提供不同的法语翻译。

\n

对此我们该怎么办?

\n

hal*_*gen 7

如果你想分离键和值,你可以调用String.init(localized:defaultValue:table:bundle:locale:comment:). 如果字符串文件中不存在该键,这允许您指定要使用的默认值,并在使用 Xcode 的导出本地化功能时用作默认翻译。

例如:

let alertMessage = String(localized: "alert.message.report-a-tap", defaultValue: "You tapped me!")

// Xcode's Export Localisations generates the following:
"alert.message.report-a-tap" = "You tapped me!";
Run Code Online (Sandbox Code Playgroud)


mat*_*att 5

我认为这是一个主要错误String(localizable:)。如果我们使用 NSLocalizedString,我们将有个体key:value:参数。String(localizable:)需要那个。

\n

我可以想到两种解决方法。一是:不要使用String(localizable:). 继续使用 NSLocalizedString 即可。

\n

另一种是明确本地化为英语。localized:输入密钥字符串,而不是输入面向用户的英语文本作为参数。然后,为了防止按键出现在用户界面中,请导出英语本地化并将按键“翻译”为所需的面向用户的英语文本。现在导入本地化以生成正确的英文.strings文件。

\n

(如果您的开发语言不是英语,请将开发语言替换为这些指令。)

\n

现在,当您导出不同的本地化版本(例如法语)时,<trans-unit>元素的id值是关键,翻译者不会关注它,而元素的<source>值是英语,翻译者会适当翻译。

\n

要稍后更改面向用户的英语文本,请编辑英语Localized.strings文件 \xe2\x80\x94 而不是代码。没有什么会破坏,因为密钥保持不变。

\n

  • 感谢您分享这个。很难相信 String(localized:) 附带了如此重大的缺陷。我目前正在使用 NSLocalizedString,但最好避免将英语“值”放入代码中,而是将所有翻译隔离为字符串文件。自从提出第二种方法以来,您还有其他的建议/建议吗? (2认同)