- Core: Schema (Codable), Store, EventBus, RPC, Engine, I18n - Controls: Text, Title1-6, Label, Input, Textarea, Number, Date, Button, Select VBox, HBox, ScrollPanel, DynamicColumn, Tabular, Form, InlineForm, TabView, Menu, PopupWindow, Html, Image, UrlWidget - Renderer: BricksView (main entry), ControlRenderer (recursive dispatch) - 30+ widget types, 9 bind actiontypes - Form validation (required/minlength/maxlength/min/max/email/number/pattern) - i18n with multi-language JSON files - 18 tests covering schema parsing, store, i18n, events
88 lines
2.5 KiB
Swift
88 lines
2.5 KiB
Swift
import Foundation
|
||
|
||
/// 国际化 — 对应Bricks的i18n系统
|
||
/// 从JSON文件加载翻译,支持语言切换
|
||
@MainActor
|
||
public final class BricksI18n: ObservableObject {
|
||
|
||
/// 当前语言(2位缩写: zh, en, ja, ko)
|
||
@Published public var locale: String = "zh"
|
||
|
||
/// 翻译字典: key → translated text
|
||
@Published public var messages: [String: String] = [:]
|
||
|
||
/// 是否启用i18n
|
||
public var enabled: Bool = true
|
||
|
||
/// i18n文件基础路径
|
||
public var basePath: String = ""
|
||
|
||
public init(locale: String = "zh") {
|
||
self.locale = locale
|
||
}
|
||
|
||
// MARK: - 加载翻译
|
||
|
||
/// 从字典加载
|
||
public func loadMessages(_ dict: [String: String]) {
|
||
messages = dict
|
||
}
|
||
|
||
/// 从JSON字符串加载
|
||
public func loadJSON(_ jsonString: String) {
|
||
guard let data = jsonString.data(using: .utf8),
|
||
let dict = try? JSONSerialization.jsonObject(with: data) as? [String: String] else { return }
|
||
messages = dict
|
||
}
|
||
|
||
/// 从URL加载翻译文件
|
||
public func loadFromURL(_ url: String) async {
|
||
guard let urlObj = URL(string: url) else { return }
|
||
do {
|
||
let (data, _) = try await URLSession.shared.data(from: urlObj)
|
||
if let dict = try? JSONSerialization.jsonObject(with: data) as? [String: String] {
|
||
messages = dict
|
||
}
|
||
} catch {
|
||
print("[SwiftBricks i18n] Failed to load: \(error)")
|
||
}
|
||
}
|
||
|
||
/// 加载指定语言的i18n文件
|
||
/// 路径格式: {basePath}/i18n/{locale}/i18n.json
|
||
public func loadLocale(_ lang: String) async {
|
||
locale = lang
|
||
guard enabled else { return }
|
||
|
||
let url = "\(basePath)/i18n/\(lang)/i18n.json"
|
||
await loadFromURL(url)
|
||
}
|
||
|
||
// MARK: - 翻译
|
||
|
||
/// 翻译文本(i18n_getmsgs风格)
|
||
public func t(_ key: String) -> String {
|
||
guard enabled else { return key }
|
||
return messages[key] ?? key
|
||
}
|
||
|
||
/// 翻译,如果未找到则返回原文
|
||
public func translate(_ text: String) -> String {
|
||
t(text)
|
||
}
|
||
|
||
// MARK: - 支持的语言
|
||
|
||
public static let supportedLocales = ["zh", "en", "ja", "ko"]
|
||
|
||
public static func localeName(_ code: String) -> String {
|
||
switch code {
|
||
case "zh": return "中文"
|
||
case "en": return "English"
|
||
case "ja": return "日本語"
|
||
case "ko": return "한국어"
|
||
default: return code
|
||
}
|
||
}
|
||
}
|