47 lines
1.6 KiB
Swift
47 lines
1.6 KiB
Swift
import Foundation
|
||
import os
|
||
|
||
/// Последний удачный ответ API.
|
||
struct MarketSnapshot: Codable, Sendable {
|
||
let date: Date
|
||
let thumbs: [SymbolThumb]
|
||
let histories: [String: [Double]]
|
||
}
|
||
|
||
/// Дисковый кэш снимка рынка в контейнере App Group.
|
||
///
|
||
/// Офлайн-фолбэк: без сети виджет показывает последние реальные котировки
|
||
/// с честной меткой времени, а не фиктивные данные.
|
||
struct MarketSnapshotCache: Sendable {
|
||
private let fileURL: URL?
|
||
|
||
private static let logger = Logger(subsystem: AppGroup.id, category: "snapshot-cache")
|
||
|
||
init() {
|
||
fileURL = AppGroup.cachesURL?.appendingPathComponent("market-snapshot.json")
|
||
}
|
||
|
||
func load() -> MarketSnapshot? {
|
||
guard let fileURL, let data = try? Data(contentsOf: fileURL) else { return nil }
|
||
do {
|
||
return try JSONDecoder().decode(MarketSnapshot.self, from: data)
|
||
} catch {
|
||
Self.logger.error("Кэш повреждён: \(String(describing: error), privacy: .public)")
|
||
return nil
|
||
}
|
||
}
|
||
|
||
func save(_ snapshot: MarketSnapshot) {
|
||
guard let fileURL else { return }
|
||
do {
|
||
try FileManager.default.createDirectory(
|
||
at: fileURL.deletingLastPathComponent(),
|
||
withIntermediateDirectories: true
|
||
)
|
||
try JSONEncoder().encode(snapshot).write(to: fileURL, options: .atomic)
|
||
} catch {
|
||
Self.logger.error("Кэш не сохранён: \(String(describing: error), privacy: .public)")
|
||
}
|
||
}
|
||
}
|