swift - Swift 包管理器本地化
问题描述
我想知道,本地化如何与 swift 包一起使用。我看到了 WWDC20/10169 视频 - Swift 包:资源和本地化。我正在尝试在自己的项目中做同样的事情。
如果我进行相同的配置(如 WWDC 视频)并添加.environment(\.locale, Locale(identifier: "es"))
到View
预览,它可以工作(但仅在 sp 内测试时)。
当我尝试在实际应用程序中使用本地化资源时,问题就开始了。这个过程非常简单——我只使用应用程序内包中的本地化字符串视图。出于测试目的,我使用特定的语言环境(方案设置)启动我的应用程序 - 结果,我总是得到en
翻译。
我的清单:
let package = Package(
name: "MyLibrary",
defaultLocalization: "en",
platforms: [
.iOS(.v14),
],
products: [
.library(
name: "MyLibrary",
targets: ["MyLibrary"]),
],
dependencies: [
],
targets: [
.target(
name: "MyLibrary",
dependencies: [],
path: "Sources"
),
.testTarget(
name: "MyLibraryTests",
dependencies: ["MyLibrary"]),
]
)
包的结构:
resource_bundle_accessor
生成得很好 - 所以我可以访问Bundle.module
,而且我确实可以按预期列出所有本地化 -en
和es
.
我还在项目本身中添加了支持的语言:
这是一个快速演示:
为了生成本地化字符串,我想使用 SwiftGen:
extension L10n {
private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
let format = BundleToken.bundle.localizedString(forKey: key, value: nil, table: table)
return String(format: format, locale: Locale.current, arguments: args)
}
}
// swiftlint:disable convenience_type
private final class BundleToken {
static let bundle: Bundle = {
#if SWIFT_PACKAGE
return Bundle.module
#else
return Bundle(for: BundleToken.self)
#endif
}()
}
// swiftlint:enable convenience_type
或者,我测试了
let text = NSLocalizedString("welcome", tableName: "Localizable", bundle: .module, value: "", comment: "")
或类似的 from Bundle
- Bundle.module.localizedString
method 和 from SwiftUI
Text("welcome", bundle: .module)
。
结果相同 - 它不会改变语言 - 我总是得到开发语言 - en
。
我还可以确认,该构建包含本地化(在 lib 包中的 testLocalization.app 内):
这是项目的链接。
所以我的问题 - 我做错了什么?错误在哪里?
解决方案
我找到了这个问题的原因 - 应用程序本身需要本地化并且在项目设置中设置它是不够的,相反,我们还应该在 info plist 中添加CFBundleLocalizations,并将所需的本地化作为字符串数组。即使在官方文档中说它只支持少数本地化,我们也可以在那里添加额外的(使用与 lproj 文件夹相同的语言环境代码),一切都会正常工作。
<key>CFBundleLocalizations</key>
<array>
<string>en</string>
<string>es</string>
<string>uk-UA</string>
</array>
来自旧的过时文档:
应用程序可以通过其信息属性列表 (Info.plist) 文件通知系统它支持其他本地化。要指定未包含在包的 .lproj 目录中的本地化,请将 CFBundleLocalizations 键添加到此文件。键的值是一个字符串数组,每个字符串都包含一个 ISO 语言指示符,如“语言和区域设置指定”中所述。</p>
像往常一样,Apple 没有在任何与 SP 相关的文档中提到这一点......
- - - 更新
正确的解决方案是“在应用程序的 Info.plist 中将CFBundleAllowMixedLocalizations设置为YES是正确的解决方案” ——来自SDGGiesbrecht
推荐阅读
- wordpress - wordpress 网站上 xmlhttprequest 的低速
- python - 运行从 Keras 转换的 tf-lite 模型对 Raspberry pi 的错误预测
- arrays - 将数据附加到数组或为每个数据点创建一个新文档是个好主意吗?
- function - Julia:如何轻松查看函数的源代码(例如 Statistics.jl 包中的 `quantile` 函数)
- python - 如何计算列表中的项目数
- java - Android 中的 WorkManager schedule_requested_at 时间等于 -1。什么意思?
- arrays - mongodb - 将对象数组(键:'keyname',值:'value')转换为名为'keyname'的字段,并具有相应的值
- javascript - Javascript matchMedia 在 iPhone X + safari 上返回相反的值
- python - 使用重试/取消对话框(在 GUI 线程中)检查 QThread 中的文件权限
- bixby - 在哪里可以找到最新的 Bixby (Viv) Library Capsules 版本?