import Foundation import IndieBackup import SwiftData /// Owns all service objects; created asynchronously at launch and injected /// into the SwiftUI environment. @Observable @MainActor final class AppServices { let modelContainer: ModelContainer let syncEngine: SyncEngine let contextService: ContextService let backupController: BackupController let audioRecorder: AudioRecorderService let transcriptionSettings: TranscriptionSettings let transcriptionService: TranscriptionService init() async { let container = NotesModelContainer.make() self.modelContainer = container let engine = SyncEngine(modelContainer: container) self.syncEngine = engine self.contextService = ContextService() self.backupController = BackupController( configuration: NotesBackupConfiguration(syncEngine: engine) ) self.audioRecorder = AudioRecorderService() let settings = TranscriptionSettings() self.transcriptionSettings = settings let transcription = TranscriptionService( syncEngine: engine, settings: settings, modelContainer: container ) self.transcriptionService = transcription // A watch recording, once ingested, is this device's to transcribe. engine.onAudioNoteIngested = { [weak transcription] id in transcription?.enqueue(noteID: id) } } /// The file extension this app owns for backup documents. Used to route /// `onOpenURL` imports to a restore. var backupFileExtension: String { backupController.configuration.backupFileExtension } /// Slow startup work (iCloud container discovery) — runs after the UI is up. func startDeferredServices() async { await syncEngine.connect() // Drain any watch recordings delivered while the app was closed — the // container is connected now, so they can be written and ingested. await syncEngine.ingestStagedWatchRecordings() // Load the supported languages / reservation cap, then pick up any of // this device's notes that were still pending when it last quit. await transcriptionSettings.prepare() transcriptionService.resumePendingWork() } }