Migrates vocabulary words and word replacements from UserDefaults to SwiftData for better data management and persistence.
Changes:
- Create VocabularyWord and WordReplacement SwiftData models
- Add dual ModelConfiguration setup (default.store for transcripts, dictionary.store for dictionary data)
- Implement DictionaryMigrationService for one-time UserDefaults→SwiftData migration
- Rename "Correct Spellings" to "Vocabulary" for clearer terminology
- Update all dictionary views to use @Query instead of manager classes
- Update all services to fetch from SwiftData using FetchDescriptor
- Enhance word replacement duplicate detection (now checks during add AND edit)
- Update import/export services to work with SwiftData
- Preserve all existing functionality with improved data integrity
Technical details:
- Separate store files: default.store (transcripts) + dictionary.store (vocabulary + replacements)
- Migration flag: "HasMigratedDictionaryToSwiftData_v2"
- All CRUD operations properly implemented with duplicate detection
- Create centralized registry for managing transcription services
- Replace duplicate switch statements across 4 manager classes
- Consolidate service initialization into single registry pattern
- Add cleanup method to registry for resource management
- Ensure fresh service registry on each transcription request
The screen capture service was selecting the first layer-0 window, which
during recording was VoiceInk's own status indicator overlay. This caused
OCR to always return 'No text detected' since the overlay has no readable
content.
Changes:
- Filter out windows owned by VoiceInk's process
- Prioritize windows belonging to NSWorkspace.frontmostApplication
- Refactor WindowCandidate struct to class scope
The screen capture service was selecting the first layer-0 window, which
during recording was VoiceInk's own status indicator overlay. This caused
OCR to always return 'No text detected' since the overlay has no readable
content.
Changes:
- Filter out windows owned by VoiceInk's process
- Prioritize windows belonging to NSWorkspace.frontmostApplication
- Filter out tiny windows (<120x120) to avoid tooltips/overlays
- Move CGWindowListCopyWindowInfo off main thread for better UI responsiveness
- Refactor WindowCandidate struct to class scope
- Replace force-unwrapped URLs in cloud transcription services with safe guard statements
* GroqTranscriptionService: Add URL validation before use
* ElevenLabsTranscriptionService: Add URL validation before use
* MistralTranscriptionService: Add URL validation before use
* OpenAICompatibleTranscriptionService: Add URL validation before use
- Replace fatalError in VoiceInk.swift with graceful degradation
* Implement in-memory fallback when persistent storage fails
* Add user notification for storage issues
* Use proper logging instead of fatal crash
- Fix dictionary force unwrap in WhisperPrompt.swift
* Add safe fallback when default language prompt missing
* Prevent potential crash on dictionary access
- Wrap debug print statement in #if DEBUG directive
* Eliminate production logging overhead in VoiceInk.swift
These changes prevent 6+ potential crash scenarios while maintaining
full functionality with graceful error handling.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>