build iOS study scaffold

This commit is contained in:
2026-04-09 15:39:32 +02:00
parent 87f152a232
commit 5c0aa9542a
12 changed files with 723 additions and 46 deletions
@@ -1,18 +1,62 @@
import Combine
import Foundation
final class LocalizationStore {
@MainActor
final class LocalizationStore: ObservableObject {
@Published private(set) var localeCode: String
private let bundle: Bundle
init(bundle: Bundle = .main) {
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 string(for key: String, locale: String) -> String {
guard let path = bundle.path(forResource: locale, ofType: "lproj"),
let localizedBundle = Bundle(path: path) else {
return bundle.localizedString(forKey: key, value: nil, table: nil)
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)
}
return localizedBundle.localizedString(forKey: key, value: nil, table: nil)
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
}
}