From fd8ca178a379da71f5bb19c461524888cad9447e Mon Sep 17 00:00:00 2001 From: Christian Cleberg Date: Fri, 17 Jul 2026 11:18:25 -0500 Subject: v4.8.0: Add scheduled report generation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ScheduledReportService (@MainActor, headless/storage-backed like DomainMonitoringService): builds the latest report for every tracked domain from persisted history, exports it via DomainReportExporter in the configured format (markdown/PDF/JSON), writes it to a local Documents subdirectory, logs the run, and fires a "Scheduled Report Ready" local notification. - ScheduledReportScheduler mirrors DomainMonitoringScheduler's BGTaskScheduler approach with its own task identifier (net.cleberg.DomainDig.report.schedule, added to Info.plist) and a daily/weekly cadence. - ScheduledReportsView (Settings → Scheduled Reports): enable toggle, cadence and format pickers, "Generate Now", and a log of past reports each shareable via the existing ExportPresenter share sheet. - Gated behind the existing .automatedMonitoring capability (Pro), consistent with monitoring being the other background-automation feature. - Settings/logs persist via UserDefaults (DomainExportFormat is now Codable), not DomainDataPortabilityService backup/restore — this is local automation configuration, not user-authored content, same reasoning as v4.7.0's watchlist saved views. --- DomainDig/DomainDigApp.swift | 3 +++ 1 file changed, 3 insertions(+) (limited to 'DomainDig/DomainDigApp.swift') diff --git a/DomainDig/DomainDigApp.swift b/DomainDig/DomainDigApp.swift index d34c51d..2f2070c 100644 --- a/DomainDig/DomainDigApp.swift +++ b/DomainDig/DomainDigApp.swift @@ -20,6 +20,7 @@ struct DomainDigApp: App { init() { LocalNotificationService.shared.configureForegroundPresentation() DomainMonitoringScheduler.shared.registerBackgroundTask() + ScheduledReportScheduler.shared.registerBackgroundTask() } var body: some Scene { @@ -38,6 +39,7 @@ struct DomainDigApp: App { localAPIService.refresh() cloudSyncService.scheduleSyncIfNeeded(trigger: .launch) viewModel.monitoringStatusMessage = DomainMonitoringScheduler.shared.syncSchedule() + ScheduledReportScheduler.shared.syncSchedule() IntegrationService.shared.processQueueNow() viewModel.refreshWidgetData() consumeShareInbox() @@ -58,6 +60,7 @@ struct DomainDigApp: App { localAPIService.refresh() cloudSyncService.scheduleSyncIfNeeded(trigger: .launch) viewModel.monitoringStatusMessage = DomainMonitoringScheduler.shared.syncSchedule() + ScheduledReportScheduler.shared.syncSchedule() IntegrationService.shared.processQueueNow() viewModel.refreshWidgetData() consumeShareInbox() -- cgit v1.2.3