Graduately/ios/Maturita/Data/Content.swift
pepaskopec-blip 6c7336c7bb Add a SwiftUI iOS app that plays the same maturita content.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 14:01:01 +02:00

95 lines
3.1 KiB
Swift

import Foundation
enum AppConfig {
static var commit: String {
let raw = (Bundle.main.object(forInfoDictionaryKey: "GITCommit") as? String)?
.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
return raw.isEmpty || raw.hasPrefix("$(") ? "dev" : raw
}
static var versionName: String {
Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "ios-1"
}
static var updateRepo: String {
(Bundle.main.object(forInfoDictionaryKey: "UPDATE_REPO") as? String)
?? "pepaskopec-blip/maturita.c"
}
static var updateBranch: String {
(Bundle.main.object(forInfoDictionaryKey: "UPDATE_BRANCH") as? String) ?? "builds"
}
}
final class Content {
let raw: J
let i18n: [String: (String?, String?)]
let subjects: [J]
let german: [J]
let net: J
let netLessons: [J]
let netTasks: [J]
let netAnswers: [[J]]
let hw: [J]
let mluvnice: [J]
let books: [J]
init(_ root: [String: Any]) {
raw = J(root)
let obj = root["i18n"] as? [String: Any] ?? [:]
var map: [String: (String?, String?)] = [:]
for (key, value) in obj {
let e = J(value)
let cs = e.strOrNull("cs")
let en = e.strOrNull("en")
map[key] = (cs, en)
}
i18n = map
subjects = raw.arr("subjects")
german = raw.arr("german")
net = raw.obj("net") ?? J([:])
netLessons = net.arr("lessons")
netTasks = net.arr("tasks")
if let a = net.o["answers"] as? [Any] {
netAnswers = a.map { block in
guard let rows = block as? [Any] else { return [] }
return rows.compactMap { item in
item is [String: Any] ? J(item) : nil
}
}
} else {
netAnswers = []
}
hw = raw.arr("hw")
mluvnice = raw.arr("mluvnice")
books = raw.arr("books")
}
func germanUnit(_ id: Int) -> J? { german.first { $0.int("id") == id } }
func netLesson(_ id: Int) -> J? { netLessons.first { $0.int("id") == id } }
func hwLesson(_ id: Int) -> J? { hw.first { $0.int("id") == id } }
func mluv(_ n: Int) -> J? { mluvnice.first { $0.int("id") == n } }
func book(_ id: String) -> J? { books.first { $0.str("id") == id } }
func tr(_ key: String?, lang: UiLang) -> String {
guard let key, !key.isEmpty else { return "" }
let hit = i18n[key]
if lang == .en { return hit?.1 ?? key }
return hit?.0 ?? key
}
func fmt(_ key: String, lang: UiLang, _ args: [CVarArg]) -> String {
let template = tr(key, lang: lang).replacingOccurrences(of: "%s", with: "%@")
return String(format: template, arguments: args)
}
static func load() -> Content {
guard let url = Bundle.main.url(forResource: "content", withExtension: "json"),
let data = try? Data(contentsOf: url),
let obj = try? JSONSerialization.jsonObject(with: data) as? [String: Any]
else {
return Content([:])
}
return Content(obj)
}
}