swift 字符串(localized:)没有单独的键和值?

af7jpaap  于 2023-01-04  发布在  Swift
关注(0)|答案(4)|浏览(189)

iOS 15新增功能,我们可以使用这个String初始化器方法在Swift代码中生成可本地化字符串:

init(localized keyAndValue: String.LocalizationValue, 
    table: String? = nil, bundle: Bundle? = nil, 
    locale: Locale = .current, comment: StaticString? = nil)

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

/* Alert message: Report a tap */
"You tapped me!" = "Vous m'avez tapé!";

那是因为我说

String(localized:"You tapped me!", comment: "Alert message: Report a tap")

并本地化为法语。
这是完全错误的!这应该是一个键-值对的列表;我们不应该使用面向用户的英语文本作为 key
首先,如果我们现在更改String(localized:comment:)调用中的英语文本,法语翻译将中断,而且,我们将无法在不同的上下文中对相同的英语文本使用不同的法语翻译。
我们该怎么办?

2izufjch

2izufjch1#

我认为这是String(localizable:)中的一个主要bug。如果我们使用NSLocalizedString,我们将有单独的key:value:参数。String(localizable:)需要这些参数。
我能想到两个解决办法。一个是:不要使用String(localizable:)。继续使用NSLocalizedString。
另一种是显式本地化为英语。输入一个键字符串,而不是输入面向用户的英语文本作为localized:参数。然后,为了防止键出现在用户界面中,导出英语本地化并将键“翻译”为所需的面向用户的英语文本。现在导入本地化以生成正确的英语 .strings 文件。
(If您的开发语言不是英语,请将开发语言替换到这些说明中。)
现在,当您导出不同的本地化版本(例如法语)时,<trans-unit>元素的id值是关键字,翻译人员不会注意它,而<source>是英语,翻译人员会适当地翻译它。
要在以后更改面向用户的英语文本,请编辑English Localizable.strings 文件-而不是代码。不会发生任何中断,因为键保持不变。

polkgigr

polkgigr2#

我在使用SwiftGen生成本地化字符串时遇到了同样的问题,解决方案是确保生成的本地化字符串文件位于相应的语言文件夹中,而不是位于单独的Generated文件夹中。

wfsdck30

wfsdck303#

使用键的显式本地化方法在这里是正确的,我认为参数名keyAndValue只是误导。
参见另一个使用String.LocalizationValue的初始化器,对于AttributedString
https://developer.apple.com/documentation/foundation/attributedstring/3867590-init
在这个例子中,参数只是被命名为key:

init(localized key: String.LocalizationValue, options: AttributedString.FormattingOptions = [], table: String? = nil, bundle: Bundle? = nil, locale: Locale? = nil, comment: StaticString? = nil)

毕竟,这似乎与SwiftUI对LocalizedStringKey的使用很好地一致,其中键旁边也没有给出值。
除了目前缺乏文档之外,我不理解引入具有所提到的LocalizedStringKeyString.LocalizationValue的必要性,但至少它似乎与SwiftUI中的方式一致,而不是与以前的localizedString(forKey:value:table)/NSLocalizedString方式一致。
在我最近的项目中,我们一直使用基于键的翻译,即使是开发语言,所以这个新的初始化器也能很好地工作。但是苹果应该改变参数名,并相应地更新文档,就像他们对AttributedString所做的那样。

mu0hgdu0

mu0hgdu04#

如果你想把键和值分开,你可以使用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!";

相关问题