// // ViewModel.swift // dns // // Created by Benjamin Erhart on 14.04.26. // import Foundation import Combine import NetworkExtension import OSLog class ViewModel: NSObject, ObservableObject { // TODO: Store this in UserDefaults @Published var blocklist: BlocklistOption = .secure // TODO: Store this in UserDefaults @Published var isDnsEnabled = false { didSet { if !isProgrammaticChange { toggleDns() } else { // Reset, so next one is recognized as coming from the user again. isProgrammaticChange = false } } } private var isProgrammaticChange = false private let manager = NEDNSSettingsManager.shared() private let log = Logger(subsystem: String(describing: ViewModel.self), category: String(describing: ViewModel.self)) func toggleDns() { Task { if isDnsEnabled { do { try await manager.loadFromPreferences() } catch { log.error("Error loading preferences: \(error)") delayedToggle(false) return } let settings = NEDNSOverHTTPSSettings(servers: [blocklist.ipv4, blocklist.ipv6]) settings.serverURL = URL(string: "https://\(blocklist.server)") settings.matchDomains = [""] manager.dnsSettings = settings manager.localizedDescription = blocklist.description do { try await manager.saveToPreferences() } catch { log.error("Error storing preferences: \(error)") delayedToggle(false) } } else { do { try await manager.removeFromPreferences() } catch { log.error("Error removing preferences: \(error)") delayedToggle(true) } } } } private func delayedToggle(_ enabled: Bool) { Task { try? await Task.sleep(nanoseconds: 500_000_000) await MainActor.run { isProgrammaticChange = true isDnsEnabled = enabled } } } }