Visual_Novel_iOS/crush/Crush/Src/Utils/LanguagesUtils.swift

255 lines
9.1 KiB
Swift
Raw Normal View History

2025-10-09 10:29:35 +00:00
//
// 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
}
}