// // LanguagesUtils.swift // LegendTeam // // Created by dong on 2022/5/18. // import Foundation //import Lottie import UIKit import RswiftResources enum Languages: String, Codable { case id case en case vi case fil case ms case th } /// api manager.. etc. class LanguagesUtils { /// default languages order // static var supportLanguages:[Languages] = [.en, .id, .ms, .vi, .fil, .th] static func initailLanguageSetting() { // #warning("test to do") // DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { // Languages.preferedLans = LanguagesUtils.getSupportSortedLanguages() // LanguagesUtils.showAppLanugagesPickVc() // } // return if let lan = AppCache.fetchCache(key: CacheKey.userAppLanguage.rawValue, type: Languages.self) { Languages.preferedLans = [lan] } else { if UserCore.shared.isLogin() { // 针对老用户(版本更新前已经注册的老用户) AppCache.cache(key: CacheKey.userAppLanguage.rawValue, value: Languages.id) Languages.preferedLans = [Languages.id] } else { // 先按系统语言显示 DispatchQueue.main.asyncAfter(deadline: .now() + 0.7) { Languages.preferedLans = LanguagesUtils.getSupportSortedLanguages() LanguagesUtils.showAppLanugagesPickVc() } } } } static func isInitialLanuageAlreadySetting()-> Bool{ if (AppCache.fetchCache(key: CacheKey.userAppLanguage.rawValue, type: Languages.self) != nil || UserCore.shared.isLogin()) { return true }else{ return false } } static func showAppLanugagesPickVc() { // let vc = LanguagesPrimarySetupController() // guard let rootVc = UIWindow.applicationKey?.rootViewController else { // assert(false) // return // } // // rootVc.addChild(vc) // rootVc.view.addSubview(vc.view) // // vc.view.snp.makeConstraints { make in // make.edges.equalToSuperview() // } } /// 语言选择sheep vc, 语言顺序按固定默认顺序了 // @discardableResult // static func showAppLanugagesPicker() -> SheetPopListSelectView { // // } // MARK: - helper /// 系统的语言顺序 static func getSystemLanguagesList() -> [String] { let lanugages = Locale.preferredLanguages.compactMap { $0.components(separatedBy: "-").first } return lanugages } /// 默认顺序, 用在系统设置中,去设置 static func languagesDict() -> [Languages] { return [.en, .id, .ms, .vi, .fil, .th] } /// 排序过后的(系统语言中有的,放到前面去),用在用户首次设置 static func getSupportSortedLanguages() -> [Languages] { // default顺序 let defaultOrderLanguages: [Languages] = LanguagesUtils.languagesDict() let systemLanguages = LanguagesUtils.getSystemLanguagesList() // ["en", "zh", "id"] var matchedArray: [Languages] = [] let matched = systemLanguages.filter { // "en", "id" for per in defaultOrderLanguages { if $0 == per.rawValue { matchedArray.append(per) return true } } return false } let otherLanguages = defaultOrderLanguages.filter { !matched.contains($0.rawValue) } return matchedArray + otherLanguages } static func deviceSavePreferLanuage(lan: Languages) { Languages.preferedLans = [lan] AppCache.cache(key: CacheKey.userAppLanguage.rawValue, value: lan) // 加载App其他相关信息 // ... } static func restartWindow() { if let appdelegate = UIApplication.shared.delegate as? AppDelegate { //appdelegate.setupWindowRootController() } else { assert(false) } NotificationCenter.post(name: .appLanugageChanged) } } extension Languages { /// 初始时尝试从配置中拉取 public static var preferedLans: [Languages] = [Languages.en] // 🔥 RSwift Library会调用 public static func preferLanguages() -> [String] { let preferLansCode = preferedLans.map { $0.rawValue } return preferLansCode + [Languages.en.rawValue] // } public static func localizedAppLanguage() -> String { let lan = preferedLans.first ?? .en return Languages.localizedLang(lan: lan) } // MARK: - helper public static func localizedLang(lan: Languages) -> String { return "en" } public static func selfLanDesc(lan: Languages) -> String { return "English" } static func regionCode(lan: Languages) -> String { return "en" } static func localRegionCode() -> String { let lan = preferedLans.first ?? .en return Languages.regionCode(lan: lan) } } @objcMembers class OCLanuagesUtils: NSObject { @objc static func localized(key: String, tableName: String, arguments: [String]?) -> String { guard let (locale, bundle) = StringResource.localeBundle(tableName: tableName, preferredLanguages: Languages.preferLanguages()) else { return key } let format = NSLocalizedString(key, tableName: tableName, bundle: bundle, comment: "") return String(format: format, locale: locale, arguments: arguments ?? []) } } extension StringResource { fileprivate static let applicationLocale = hostingBundle.preferredLocalizations.first.flatMap { Locale(identifier: $0) } ?? Locale.current fileprivate static let hostingBundle = Bundle.main public func localized(_ values: [String] = [""]) -> String { // 替换规则说明: R.string.localizable.home.localized() -> R.string.localizable.home.localized.localized() guard let (locale, bundle) = StringResource.localeBundle(tableName: tableName, preferredLanguages: Languages.preferLanguages()) else { return key.description } let format = NSLocalizedString(key.description, tableName: tableName, bundle: bundle, comment: "") return String(format: format, locale: locale, arguments: values) // String(format: format, locale: locale, values) } /// Find first language and bundle for which the table exists fileprivate static func localeBundle(tableName: String, preferredLanguages: [String]) -> (Foundation.Locale, Foundation.Bundle)? { // Filter preferredLanguages to localizations, use first locale var languages = preferredLanguages .map { Locale(identifier: $0) } .prefix(1) .flatMap { locale -> [String] in if hostingBundle.localizations.contains(locale.identifier) { if let language = locale.languageCode, hostingBundle.localizations.contains(language) { return [locale.identifier, language] } else { return [locale.identifier] } } else if let language = locale.languageCode, hostingBundle.localizations.contains(language) { return [language] } else { return [] } } // If there's no languages, use development language as backstop if languages.isEmpty { if let developmentLocalization = hostingBundle.developmentLocalization { languages = [developmentLocalization] } } else { // Insert Base as second item (between locale identifier and languageCode) languages.insert("Base", at: 1) // Add development language as backstop if let developmentLocalization = hostingBundle.developmentLocalization { languages.append(developmentLocalization) } } // Find first language for which table exists // Note: key might not exist in chosen language (in that case, key will be shown) for language in languages { if let lproj = hostingBundle.url(forResource: language, withExtension: "lproj"), let lbundle = Bundle(url: lproj) { let strings = lbundle.url(forResource: tableName, withExtension: "strings") let stringsdict = lbundle.url(forResource: tableName, withExtension: "stringsdict") if strings != nil || stringsdict != nil { return (Locale(identifier: language), lbundle) } } } // If table is available in main bundle, don't look for localized resources let strings = hostingBundle.url(forResource: tableName, withExtension: "strings", subdirectory: nil, localization: nil) let stringsdict = hostingBundle.url(forResource: tableName, withExtension: "stringsdict", subdirectory: nil, localization: nil) if strings != nil || stringsdict != nil { return (applicationLocale, hostingBundle) } // If table is not found for requested languages, key will be shown return nil } }