Swift包管理器本地化

10

我想知道swift package如何进行本地化。我看了WWDC20/10169视频 - Swift packages: Resources and localization。我正在尝试在自己的项目中做同样的事情。

如果我按照视频中的配置,将.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,并且我也可以按预期列出所有本地化文本 - enes

我还将支持的语言添加到了项目本身中:

支持的语言

这是一个快速的演示:

演示

为了生成本地化字符串,我想使用 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: "")

BundleBundle.module.localizedString方法和SwiftUIText("welcome", bundle: .module)中获取的结果相同,但不会更改语言,我始终得到开发语言 - en

我还可以确认,该构建包含本地化(在lib包中的testLocalization.app内):

testLocalization.app

这里是项目链接

我的问题是 - 我做错了什么?错误在哪里?

1个回答

11
我找到了这个问题的原因 - 应用程序本身需要本地化,并且在项目设置中设置它是不够的,我们还应该在信息属性列表(info plist)中添加CFBundleLocalizations作为字符串数组的必需本地化。即使在官方文档中说仅支持少数本地化,我们仍然可以在其中添加其他本地化(使用与lproj文件夹相同的地区代码),一切都将正常工作。
<key>CFBundleLocalizations</key>
<array>
    <string>en</string>
    <string>es</string>
    <string>uk-UA</string>
</array>

从旧的过时文档中:

一个应用程序可以通过其信息属性列表(Info.plist)文件通知系统它支持其他本地化。要指定未包含在您的束的.lproj目录中的本地化,请将CFBundleLocalizations键添加到此文件中。该键的值是字符串数组,每个字符串都包含ISO语言标识符,如“语言和区域设置标识”中所述。

通常情况下,苹果没有在任何与SP相关的文档中提到这一点...

----- 更新

正确的解决方案是 "在应用程序的 Info.plist 中将 CFBundleAllowMixedLocalizations 设置为 YES 是正确的解决方案" - 来自 SDGGiesbrecht


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接