63 lines
1.8 KiB
Swift
63 lines
1.8 KiB
Swift
import Combine
|
|
import Foundation
|
|
|
|
@MainActor
|
|
final class LocalizationStore: ObservableObject {
|
|
@Published private(set) var localeCode: String
|
|
|
|
private let bundle: Bundle
|
|
|
|
private static let supportedLocaleCodes = ["en", "sv"]
|
|
private static let fallbackLocaleCode = "en"
|
|
|
|
init(bundle: Bundle = .main, localeCode: String = Locale.preferredLanguages.first.map { String($0.prefix(2)) } ?? "en") {
|
|
self.bundle = bundle
|
|
self.localeCode = Self.normalize(localeCode)
|
|
}
|
|
|
|
func setLocale(_ localeCode: String) {
|
|
self.localeCode = Self.normalize(localeCode)
|
|
}
|
|
|
|
func string(for key: String) -> String {
|
|
string(for: key, localeCode: localeCode)
|
|
}
|
|
|
|
func string(for key: String, localeCode: String) -> String {
|
|
guard let localizedBundle = localizedBundle(for: localeCode) else {
|
|
return fallbackString(for: key, localeCode: localeCode)
|
|
}
|
|
|
|
let value = localizedBundle.localizedString(forKey: key, value: nil, table: nil)
|
|
if value == key {
|
|
return fallbackString(for: key, localeCode: localeCode)
|
|
}
|
|
|
|
return value
|
|
}
|
|
|
|
private func fallbackString(for key: String, localeCode: String) -> String {
|
|
guard localeCode != Self.fallbackLocaleCode else {
|
|
return key
|
|
}
|
|
|
|
return string(for: key, localeCode: Self.fallbackLocaleCode)
|
|
}
|
|
|
|
private func localizedBundle(for localeCode: String) -> Bundle? {
|
|
guard let path = bundle.path(forResource: localeCode, ofType: "lproj") else {
|
|
return nil
|
|
}
|
|
|
|
return Bundle(path: path)
|
|
}
|
|
|
|
private static func normalize(_ localeCode: String) -> String {
|
|
guard supportedLocaleCodes.contains(localeCode) else {
|
|
return fallbackLocaleCode
|
|
}
|
|
|
|
return localeCode
|
|
}
|
|
}
|