255 lines
9.1 KiB
Swift
255 lines
9.1 KiB
Swift
|
|
//
|
|||
|
|
// 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
|
|||
|
|
}
|
|||
|
|
}
|