mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
135 lines
4.7 KiB
Swift
135 lines
4.7 KiB
Swift
import Foundation
|
|
|
|
// Assuming NGLogging and AppBundle are custom modules, they are imported here.
|
|
import SGLogging
|
|
import AppBundle
|
|
|
|
|
|
public let SGFallbackLocale = "en"
|
|
|
|
public class SGLocalizationManager {
|
|
|
|
public static let shared = SGLocalizationManager()
|
|
|
|
private let appBundle: Bundle
|
|
private var localizations: [String: [String: String]] = [:]
|
|
private var webLocalizations: [String: [String: String]] = [:]
|
|
private let fallbackMappings: [String: String] = [
|
|
// "from": "to"
|
|
"zh-hant": "zh-hans",
|
|
"be": "ru",
|
|
"nb": "no",
|
|
"ckb": "ku",
|
|
"sdh": "ku"
|
|
]
|
|
|
|
private init(fetchLocale: String = SGFallbackLocale) {
|
|
self.appBundle = getAppBundle()
|
|
// Iterating over all the app languages and loading SGLocalizable.strings
|
|
self.appBundle.localizations.forEach { locale in
|
|
if locale != "Base" {
|
|
localizations[locale] = loadLocalDictionary(for: locale)
|
|
}
|
|
}
|
|
// Downloading one specific locale
|
|
self.downloadLocale(fetchLocale)
|
|
}
|
|
|
|
public func localizedString(_ key: String, _ locale: String = SGFallbackLocale, args: CVarArg...) -> String {
|
|
let sanitizedLocale = self.sanitizeLocale(locale)
|
|
|
|
if let localizedString = findLocalizedString(forKey: key, inLocale: sanitizedLocale) {
|
|
if args.isEmpty {
|
|
return String(format: localizedString)
|
|
} else {
|
|
return String(format: localizedString, arguments: args)
|
|
}
|
|
}
|
|
|
|
SGLogger.shared.log("Strings", "Missing string for key: \(key) in locale: \(locale)")
|
|
return key
|
|
}
|
|
|
|
private func loadLocalDictionary(for locale: String) -> [String: String] {
|
|
guard let path = self.appBundle.path(forResource: "SGLocalizable", ofType: "strings", inDirectory: nil, forLocalization: locale) else {
|
|
// SGLogger.shared.log("Localization", "Unable to find path for locale: \(locale)")
|
|
return [:]
|
|
}
|
|
|
|
guard let dictionary = NSDictionary(contentsOf: URL(fileURLWithPath: path)) as? [String: String] else {
|
|
// SGLogger.shared.log("Localization", "Unable to load dictionary for locale: \(locale)")
|
|
return [:]
|
|
}
|
|
|
|
return dictionary
|
|
}
|
|
|
|
public func downloadLocale(_ locale: String) {
|
|
#if DEBUG
|
|
SGLogger.shared.log("Strings", "DEBUG ignoring locale download: \(locale)")
|
|
if ({ return true }()) {
|
|
return
|
|
}
|
|
#endif
|
|
let sanitizedLocale = self.sanitizeLocale(locale)
|
|
guard let url = URL(string: self.getStringsUrl(for: sanitizedLocale)) else {
|
|
SGLogger.shared.log("Strings", "Invalid URL for locale: \(sanitizedLocale)")
|
|
return
|
|
}
|
|
|
|
DispatchQueue.global(qos: .background).async {
|
|
if let localeDict = NSDictionary(contentsOf: url) as? [String: String] {
|
|
DispatchQueue.main.async {
|
|
self.webLocalizations[sanitizedLocale] = localeDict
|
|
SGLogger.shared.log("Strings", "Successfully downloaded locale \(sanitizedLocale)")
|
|
}
|
|
} else {
|
|
SGLogger.shared.log("Strings", "Failed to download \(sanitizedLocale)")
|
|
}
|
|
}
|
|
}
|
|
|
|
private func sanitizeLocale(_ locale: String) -> String {
|
|
var sanitizedLocale = locale
|
|
let rawSuffix = "-raw"
|
|
if locale.hasSuffix(rawSuffix) {
|
|
sanitizedLocale = String(locale.dropLast(rawSuffix.count))
|
|
}
|
|
|
|
if sanitizedLocale == "pt-br" {
|
|
sanitizedLocale = "pt"
|
|
} else if sanitizedLocale == "nb" {
|
|
sanitizedLocale = "no"
|
|
}
|
|
|
|
return sanitizedLocale
|
|
}
|
|
|
|
private func findLocalizedString(forKey key: String, inLocale locale: String) -> String? {
|
|
if let string = self.webLocalizations[locale]?[key], !string.isEmpty {
|
|
return string
|
|
}
|
|
if let string = self.localizations[locale]?[key], !string.isEmpty {
|
|
return string
|
|
}
|
|
if let fallbackLocale = self.fallbackMappings[locale] {
|
|
return self.findLocalizedString(forKey: key, inLocale: fallbackLocale)
|
|
}
|
|
return self.localizations[SGFallbackLocale]?[key]
|
|
}
|
|
|
|
private func getStringsUrl(for locale: String) -> String {
|
|
return "https://raw.githubusercontent.com/Swiftgram/Telegram-iOS/master/Swiftgram/SGStrings/Strings/\(locale).lproj/SGLocalizable.strings"
|
|
}
|
|
|
|
}
|
|
|
|
public let i18n = SGLocalizationManager.shared.localizedString
|
|
|
|
|
|
public extension String {
|
|
func i18n(_ locale: String = SGFallbackLocale, args: CVarArg...) -> String {
|
|
return SGLocalizationManager.shared.localizedString(self, locale, args: args)
|
|
}
|
|
}
|