// // CLUI.swift // Crush // // Created by Leon on 2025/7/11. // import Foundation let EPConfigShadowPrefix = "@SHA:" let EPConfigGradientPrefix = "@GRA:" class CLBaseTokens { static var shared = CLBaseTokens() // MARK: - Properties var globalTokens: [String: Any]? var sysDarkTokens: [String: Any]? var sysLightTokens: [String: Any]? var globalKeys: [String]? var sysDarkKeys: [String]? var sysLightKeys: [String]? // MARK: - Singleton // static let shared = CLBaseTokens() init() { initialTokens() } // MARK: - Initial private func initialTokens() { // 加载 global tokens if let json1Path = Bundle.main.path(forResource: "token_global", ofType: "json"), let json1Data = try? Data(contentsOf: URL(fileURLWithPath: json1Path)), let dict1 = try? JSONSerialization.jsonObject(with: json1Data, options: []) as? [String: Any] { globalTokens = dict1 globalKeys = dict1.keys.sorted() //assert(dict1 != nil, "json should be valid") } // 加载 sysDark tokens if let json2Path = Bundle.main.path(forResource: "token_sys_normal", ofType: "json"), let json2Data = try? Data(contentsOf: URL(fileURLWithPath: json2Path)), let dict2 = try? JSONSerialization.jsonObject(with: json2Data, options: []) as? [String: Any] { sysDarkTokens = dict2 sysDarkKeys = dict2.keys.sorted() } assert(sysDarkTokens != nil) } // MARK: - Public Methods /// ⚠️ 只针对单 token 的情况,保留此方法,不推荐使用 func getTokenByKey(_ key: String) -> String { var value: String? if let sysDarkKeys = sysDarkKeys, sysDarkKeys.contains(key) { value = sysDarkTokens?[key] as? String } if value == nil, let globalKeys = globalKeys, globalKeys.contains(key) { value = globalTokens?[key] as? String } guard let finalValue = value else { print("\(key) UI Token Key may doesn't exist") return "" } if finalValue.contains("$") { let keyNew = finalValue.replacingOccurrences(of: "$", with: "") return getTokenByKey(keyNew) } return finalValue } func getTokensByKey(_ key: String) -> [String] { var value: String? if let sysKeys = sysDarkKeys { if sysKeys.contains(key){ value = sysDarkTokens?[key] as? String } } if value == nil, let globalKeys = globalKeys, globalKeys.contains(key) { value = globalTokens?[key] as? String } guard let finalValue = value else { print("❌\(key)❌ UI Token Key doesn't exist ❌❌") return [] } let params = finalValue.components(separatedBy: ",") var arrayM: [String] = [] for per in params { let dealPer = per.trimmingCharacters(in: .whitespacesAndNewlines) if dealPer.contains("$") { var keyNew = dealPer keyNew = keyNew.replacingOccurrences(of: EPConfigShadowPrefix, with: "") keyNew = keyNew.replacingOccurrences(of: EPConfigGradientPrefix, with: "") if keyNew.contains("&") { let keys = keyNew.components(separatedBy: "&") var multi: [String] = [] for perKey in keys { let keyNew2 = perKey.replacingOccurrences(of: "$", with: "") let value = getTokenByKey(keyNew2) multi.append(value) } let covertValues = multi.joined(separator: "&") arrayM.append(covertValues) } else { var values: [String] = [] var tempKey = keyNew while tempKey.contains("$") { tempKey = tempKey.replacingOccurrences(of: "$", with: "") values = getTokensByKey(tempKey) arrayM.append(contentsOf: values) } } } else { arrayM.append(dealPer) } } return arrayM } // MARK: - Always Dark /// ⚠️ 只针对单 token 的情况,保留此方法,不推荐使用 func getDarkToken(_ key: String) -> String { var value: String? if let sysDarkKeys = sysDarkKeys, sysDarkKeys.contains(key) { value = sysDarkTokens?[key] as? String } if value == nil, let globalKeys = globalKeys, globalKeys.contains(key) { value = globalTokens?[key] as? String } guard let finalValue = value else { print("❌\(key)❌ UI Token Key doesn't exist ❌❌") return "" } if finalValue.contains("$") { let keyNew = finalValue.replacingOccurrences(of: "$", with: "") return getTokenByKey(keyNew) } return finalValue } func getDarkTokens(_ key: String) -> [String] { var value: String? if let sysDarkKeys = sysDarkKeys, sysDarkKeys.contains(key) { value = sysDarkTokens?[key] as? String } if value == nil, let globalKeys = globalKeys, globalKeys.contains(key) { value = globalTokens?[key] as? String } guard let finalValue = value else { print("❌\(key)❌ UI Token Key doesn't exist ❌❌") return [] } let params = finalValue.components(separatedBy: ",") var arrayM: [String] = [] for per in params { let dealPer = per.trimmingCharacters(in: .whitespacesAndNewlines) if dealPer.contains("$") { var keyNew = dealPer keyNew = keyNew.replacingOccurrences(of: EPConfigShadowPrefix, with: "") keyNew = keyNew.replacingOccurrences(of: EPConfigGradientPrefix, with: "") var values: [String] = [] while keyNew.contains("$") { keyNew = keyNew.replacingOccurrences(of: "$", with: "") values = getTokensByKey(keyNew) arrayM.append(contentsOf: values) } } else { arrayM.append(dealPer) } } return arrayM } }