Files
openless/Sources/OpenLessPersistence/HistoryStore.swift
T

52 lines
1.8 KiB
Swift

import Foundation
import OpenLessCore
/// v1 demo 简化版历史:JSON 文件 append;后续切 SQLite。
public final class HistoryStore: @unchecked Sendable {
private let fileURL: URL
private let lock = NSLock()
private let encoder = JSONEncoder()
private let decoder = JSONDecoder()
public init() {
encoder.dateEncodingStrategy = .iso8601
decoder.dateDecodingStrategy = .iso8601
let dir = FileManager.default
.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0]
.appendingPathComponent("OpenLess", isDirectory: true)
try? FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true)
self.fileURL = dir.appendingPathComponent("history.json")
if !FileManager.default.fileExists(atPath: fileURL.path) {
FileManager.default.createFile(atPath: fileURL.path, contents: "[]".data(using: .utf8))
}
}
public func save(_ session: DictationSession) {
lock.lock()
defer { lock.unlock() }
var sessions = loadAll()
sessions.insert(session, at: 0)
if sessions.count > 200 { sessions = Array(sessions.prefix(200)) }
if let data = try? encoder.encode(sessions) {
try? data.write(to: fileURL, options: .atomic)
}
}
public func recent(limit: Int = 50) -> [DictationSession] {
lock.lock()
defer { lock.unlock() }
return Array(loadAll().prefix(limit))
}
public func clear() {
lock.lock()
defer { lock.unlock() }
try? "[]".data(using: .utf8)?.write(to: fileURL)
}
private func loadAll() -> [DictationSession] {
guard let data = try? Data(contentsOf: fileURL) else { return [] }
return (try? decoder.decode([DictationSession].self, from: data)) ?? []
}
}