fix crash on stop recording

- Remove #Predicate with local variable capture (known SwiftData crash)
- Explicitly insert VoiceMemo into context before relationship assignment
- Save context before starting async transcription
- Extract audioURL before Task boundary to avoid cross-context access

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-15 23:09:44 +01:00
parent 5b3f165f6e
commit c64f6627cb

View File

@@ -40,25 +40,27 @@ final class RecordingViewModel {
audioFileName: result.url.lastPathComponent,
duration: result.duration
)
context.insert(memo)
memo.entry = entry
entry.memos.append(memo)
entry.updatedAt = .now
try? context.save()
let audioURL = memo.audioURL
Task {
await transcribeMemo(memo, context: context)
await transcribeMemo(memo, audioURL: audioURL)
}
}
private func fetchOrCreateEntry(for date: Date, context: ModelContext) -> DiaryEntry {
let startOfDay = Calendar.current.startOfDay(for: date)
let endOfDay = Calendar.current.date(byAdding: .day, value: 1, to: startOfDay)!
let descriptor = FetchDescriptor<DiaryEntry>()
var descriptor = FetchDescriptor<DiaryEntry>(
predicate: #Predicate { $0.date >= startOfDay && $0.date < endOfDay }
)
descriptor.fetchLimit = 1
if let existing = try? context.fetch(descriptor).first {
return existing
if let entries = try? context.fetch(descriptor) {
let match = entries.first { entry in
Calendar.current.isDate(entry.date, inSameDayAs: date)
}
if let match { return match }
}
let entry = DiaryEntry(date: date)
@@ -66,7 +68,7 @@ final class RecordingViewModel {
return entry
}
private func transcribeMemo(_ memo: VoiceMemo, context: ModelContext) async {
private func transcribeMemo(_ memo: VoiceMemo, audioURL: URL) async {
if transcriptionService.authorizationStatus == .notDetermined {
await transcriptionService.requestAuthorization()
}
@@ -76,13 +78,14 @@ final class RecordingViewModel {
}
memo.isTranscribing = true
defer { memo.isTranscribing = false }
do {
let transcript = try await transcriptionService.transcribe(audioURL: memo.audioURL)
let transcript = try await transcriptionService.transcribe(audioURL: audioURL)
memo.transcript = transcript
memo.isTranscribing = false
memo.entry?.updatedAt = .now
} catch {
memo.isTranscribing = false
self.error = error
}
}