不使用Localizable.strings的SwiftUI本地化系统



我第一次使用XCodes本地化策略。我觉得用起来有点不舒服。。。一个应用程序中有数百个可本地化的字符串,我想知道是否没有更好的方法

不太讨人喜欢的是缺少类型安全性,包括可能对字符串属性进行全局重命名、编译时一致性检查(所有内容都已翻译?(、可维护性。名单还在继续。

建议书

我写了一份不同方法的草稿。(这纯粹是为了SwiftUI环境,没有考虑任何Storyboard本地化(

我想知道这个解决方案是否有什么问题,可能会禁止使用它这会在应用程序审查中被接受吗?(为什么不呢?(
在做了一些研究之后,我想知道为什么每个人似乎都只使用枚举替换字符串名称,也许还使用了一些外部工具。



这将是要访问的顶级对象(稍后需要名称间隔(:

enum Localizables {
case headlineForSomething
case bodytext
case somethingElse
case buttonTitle
}



实际的翻译结果存在于这些扩展中
每个扩展都存在于一个单独的文件.swift中。相当于Localizable.strings/Language X:

extension Localizables {
private var en: String {
switch self {
case .headlineForSomething:
return "Headline for something in English"
case .bodytext:
return "Bodytext in English"
case .somethingElse:
return "Something else in English"
case .buttonTitle:
return "Button title in English"
}
}
}

extension Localizables {
private var de: String {
switch self {
case .headlineForSomething:
return "Headline for something in German"
case .bodytext:
return "Bodytext in German"
case .somethingElse:
return "Something else in German"
case .buttonTitle:
return "Button title in German"
}
}
}



系统的简单核心
1。包含的语言必须首先列出
2.此属性与生成的字符串一起公开。

extension Localizables {
// 1: 
private var availableLocales: [Language] {
[
Language(ressources: self.en, name: "en"),
Language(ressources: self.de, name: "de")
]
}
// 2:
var localized: String {
return self.translate()
}
private func translate() -> String {
for lang in self.availableLocales {
if Locale.current.languageCode == lang.name {
return lang.ressources
}
else { return "not tranlated" }
}
return "not tranlated xxx"
}
}
struct Language {
let ressources: String
let name: String
}



我的小方法的用法很简单:

let someStringToBeLocalized: String = Localizables.headlineForSomething.localized



我看到的当前ToDos和缺点:

为了更好地访问,案例当然必须以名称隔开案例可以(?(包括变量,将数字等计算属性插入到例如句子中。我不确定翻译服务提供商是否会使用Localizable.string文件以外的其他文件。再说一遍:为什么不呢?



您可以尝试保留自定义实现,并通过使用从视图中获取locale的技巧来支持SwiftUI提供的.environment。当EnvironmentValue通过视图层次结构传播时,需要进行特殊处理。

为了扭转你的优势,你可以提供

struct LocalizedText: View {
@Environment(.locale) var locale
let key: String
let localizedString: (_ languageCode: String?, _ key: String) -> (String)
var body: Text {
let languageCode = locale.languageCode ?? Locale.current.languageCode
let localizedString = localizedString(languageCode, key)
return Text(localizedString)
}
}

拥有:

extension Localizables {
static func localizedString(_ key: String, languageCode: String) -> String {
... // do what is required in your case
}
static func localizedText(_ key: String) -> some View {
LocalizedText(key: key, localizedString: { languageCode, key in
localizedString(key, languageCode: languageCode)
})
}
}

我写了一篇关于这个的博客文章。

最新更新