krz/domain-dig

an ios app for DNS & SSL analysis

clone: git clone https://gitbay.org/krz/domain-dig.git

v4.9.0: DomainDig/DomainDigApp.swift · raw

 1//
 2//  DomainDigApp.swift
 3//  DomainDig
 4//
 5//  Created by cmc on 2026-03-10.
 6//
 7
 8import SwiftUI
 9
10@main
11struct DomainDigApp: App {
12    @UIApplicationDelegateAdaptor(DomainDigAppDelegate.self) private var appDelegate
13    @Environment(\.scenePhase) private var scenePhase
14    @AppStorage(AppDensity.userDefaultsKey) private var density = AppDensity.compact.rawValue
15    @AppStorage(AppAppearance.userDefaultsKey) private var appearance = AppAppearance.system.rawValue
16    @State private var viewModel = DomainViewModel()
17    @State private var purchaseService = PurchaseService.shared
18    @State private var cloudSyncService = CloudSyncService.shared
19    @State private var localAPIService = LocalAPIService.shared
20
21    init() {
22        LocalNotificationService.shared.configureForegroundPresentation()
23        DomainMonitoringScheduler.shared.registerBackgroundTask()
24        ScheduledReportScheduler.shared.registerBackgroundTask()
25    }
26
27    var body: some Scene {
28        WindowGroup {
29            RootTabView(viewModel: viewModel)
30                .environment(\.appDensity, AppDensity(rawValue: density) ?? .compact)
31                // The single place appearance is applied. Keep it that way.
32                .preferredColorScheme((AppAppearance(rawValue: appearance) ?? .system).colorScheme)
33                .task {
34                    #if DEBUG
35                    viewModel.seedAuditFixturesIfRequested()
36                    #endif
37                    let _ = purchaseService.currentTier
38                    let _ = cloudSyncService.status
39                    let _ = localAPIService.isRunning
40                    let _ = IntegrationService.shared.targets.count
41                    await purchaseService.refreshEntitlements()
42                    viewModel.refreshMonitoringState()
43                    await viewModel.refreshMonitoringAuthorizationStatus()
44                    await cloudSyncService.refreshAvailability()
45                    localAPIService.refresh()
46                    cloudSyncService.scheduleSyncIfNeeded(trigger: .launch)
47                    viewModel.monitoringStatusMessage = DomainMonitoringScheduler.shared.syncSchedule()
48                    ScheduledReportScheduler.shared.syncSchedule()
49                    IntegrationService.shared.processQueueNow()
50                    viewModel.refreshWidgetData()
51                    consumeShareInbox()
52                }
53                .onReceive(NotificationCenter.default.publisher(for: .cloudSyncDidApplyChanges)) { _ in
54                    viewModel.refreshPersistedData()
55                    viewModel.monitoringStatusMessage = DomainMonitoringScheduler.shared.syncSchedule()
56                    IntegrationService.shared.refresh()
57                }
58        }
59        .onChange(of: scenePhase) { _, newValue in
60            guard newValue == .active else { return }
61            viewModel.refreshMonitoringState()
62            Task {
63                await viewModel.refreshMonitoringAuthorizationStatus()
64                await cloudSyncService.refreshAvailability()
65            }
66            localAPIService.refresh()
67            cloudSyncService.scheduleSyncIfNeeded(trigger: .launch)
68            viewModel.monitoringStatusMessage = DomainMonitoringScheduler.shared.syncSchedule()
69            ScheduledReportScheduler.shared.syncSchedule()
70            IntegrationService.shared.processQueueNow()
71            viewModel.refreshWidgetData()
72            consumeShareInbox()
73        }
74    }
75
76    /// Picks up a domain shared via the share extension and routes it into an
77    /// inspection through the intent router (consumed by `RootTabView`).
78    private func consumeShareInbox() {
79        guard let domain = DomainDigShareInbox.consume() else { return }
80        DomainDigIntentRouter.shared.pendingAction = .inspect(domain)
81    }
82}