add save function of explanation
This commit is contained in:
47
ios/OralTrainer/Services/SentenceExplanationStore.swift
Normal file
47
ios/OralTrainer/Services/SentenceExplanationStore.swift
Normal file
@@ -0,0 +1,47 @@
|
||||
import Foundation
|
||||
|
||||
final class SentenceExplanationStore {
|
||||
static let shared = SentenceExplanationStore()
|
||||
|
||||
private let root: URL
|
||||
|
||||
init() {
|
||||
let documents = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
|
||||
root = documents.appendingPathComponent("SentenceExplanations", isDirectory: true)
|
||||
try? FileManager.default.createDirectory(at: root, withIntermediateDirectories: true)
|
||||
}
|
||||
|
||||
func load(mediaId: String, sentenceIndex: Int) -> String? {
|
||||
let url = fileURL(mediaId: mediaId, sentenceIndex: sentenceIndex)
|
||||
guard FileManager.default.fileExists(atPath: url.path) else { return nil }
|
||||
let text = try? String(contentsOf: url, encoding: .utf8)
|
||||
let trimmed = text?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
|
||||
return trimmed.isEmpty ? nil : trimmed
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
func save(mediaId: String, sentenceIndex: Int, explanation: String) -> Bool {
|
||||
let trimmed = explanation.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
guard !trimmed.isEmpty else { return false }
|
||||
let url = fileURL(mediaId: mediaId, sentenceIndex: sentenceIndex)
|
||||
try? FileManager.default.createDirectory(at: url.deletingLastPathComponent(), withIntermediateDirectories: true)
|
||||
do {
|
||||
try trimmed.write(to: url, atomically: true, encoding: .utf8)
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
private func fileURL(mediaId: String, sentenceIndex: Int) -> URL {
|
||||
let directory = root.appendingPathComponent(Self.sanitize(mediaId), isDirectory: true)
|
||||
return directory.appendingPathComponent("\(sentenceIndex).txt")
|
||||
}
|
||||
|
||||
static func sanitize(_ mediaId: String) -> String {
|
||||
let allowed = CharacterSet.alphanumerics.union(CharacterSet(charactersIn: "._-"))
|
||||
let filtered = mediaId.lowercased().unicodeScalars.map { allowed.contains($0) ? Character($0) : "_" }
|
||||
let value = String(filtered).trimmingCharacters(in: CharacterSet(charactersIn: "_"))
|
||||
return value.isEmpty || value == "." || value == ".." ? "unknown" : value
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user