Compare commits

...

5 commits

6 changed files with 121 additions and 28 deletions

View file

@ -269,7 +269,7 @@
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@ -305,7 +305,7 @@
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",

View file

@ -6,6 +6,7 @@
//
import Foundation
import NetworkExtension
enum BlocklistOption: String, CaseIterable, Identifiable {
case secure = "Secure"
@ -66,4 +67,12 @@ enum BlocklistOption: String, CaseIterable, Identifiable {
return "2001:db8::1"
}
}
var settings: NEDNSOverHTTPSSettings {
let settings = NEDNSOverHTTPSSettings(servers: [ipv4, ipv6])
settings.serverURL = URL(string: "https://\(server)/dns-query")
settings.matchDomains = [""]
return settings
}
}

View file

@ -48,7 +48,7 @@ struct HomeView: View {
private let privacyPolicyURL = URL(string: "https://www.sr2.uk/privacy")!
var body: some View {
NavigationStack {
NavigationCompat {
List {
// Main toggle section

View file

@ -0,0 +1,32 @@
//
// NavigationCompat.swift
// dns
//
// Created by Benjamin Erhart on 15.04.26.
//
import SwiftUI
struct NavigationCompat<Content: View>: View {
let content: () -> Content
init(@ViewBuilder content: @escaping () -> Content) {
self.content = content
}
var body: some View {
if #available(iOS 16.0, macOS 13.0, *) {
NavigationStack {
content()
}
}
else {
NavigationView {
content()
}
#if !os(macOS)
.navigationViewStyle(StackNavigationViewStyle())
#endif
}
}
}

24
dns/Settings.swift Normal file
View file

@ -0,0 +1,24 @@
//
// Settings.swift
// dns
//
// Created by Benjamin Erhart on 15.04.26.
//
import Foundation
class Settings {
private static let blocklistKey = "blocklist"
private static let defaults = UserDefaults.standard
class var blocklist: BlocklistOption {
get {
BlocklistOption(rawValue: defaults.string(forKey: blocklistKey) ?? BlocklistOption.secure.rawValue) ?? .secure
}
set {
defaults.set(newValue.rawValue, forKey: blocklistKey)
}
}
}

View file

@ -12,24 +12,27 @@ 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 {
var blocklist: BlocklistOption = .secure {
didSet {
if !isProgrammaticChange {
Settings.blocklist = blocklist
if isDnsEnabled {
toggleDns()
}
else {
// Reset, so next one is recognized as coming from the user again.
isProgrammaticChange = false
}
}
}
@Published
var isDnsEnabled = false {
didSet {
toggleDns()
}
}
private var isProgrammaticChange = false
@ -38,26 +41,51 @@ class ViewModel: NSObject, ObservableObject {
private let log = Logger(subsystem: String(describing: ViewModel.self), category: String(describing: ViewModel.self))
func toggleDns() {
override init() {
super.init()
isProgrammaticChange = true
blocklist = Settings.blocklist
Task {
if isDnsEnabled {
do {
try await manager.loadFromPreferences()
}
catch {
log.error("Error loading preferences: \(error)")
delayedToggle(false)
return
}
if let settings = manager.dnsSettings {
for dnsServer in BlocklistOption.allCases {
if settings.servers.contains(dnsServer.ipv4) {
await MainActor.run {
isProgrammaticChange = true
blocklist = dnsServer
isProgrammaticChange = true
isDnsEnabled = true
}
break
}
}
}
}
}
func toggleDns() {
guard !isProgrammaticChange else {
// Reset, so next one is recognized as coming from the user again.
isProgrammaticChange = false
return
}
let settings = NEDNSOverHTTPSSettings(servers: [blocklist.ipv4, blocklist.ipv6])
settings.serverURL = URL(string: "https://\(blocklist.server)")
settings.matchDomains = [""]
manager.dnsSettings = settings
Task {
if isDnsEnabled {
manager.dnsSettings = blocklist.settings
manager.localizedDescription = blocklist.description
do {