Compare commits
5 commits
a6f8add14a
...
603a23a1a8
| Author | SHA1 | Date | |
|---|---|---|---|
| 603a23a1a8 | |||
| 8c1716de77 | |||
| 6cbad66a87 | |||
| 807176f0b5 | |||
| 6ca509f7fb |
6 changed files with 121 additions and 28 deletions
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
32
dns/NavigationCompat.swift
Normal file
32
dns/NavigationCompat.swift
Normal 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
24
dns/Settings.swift
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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))
|
||||
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
isProgrammaticChange = true
|
||||
blocklist = Settings.blocklist
|
||||
|
||||
Task {
|
||||
do {
|
||||
try await manager.loadFromPreferences()
|
||||
}
|
||||
catch {
|
||||
log.error("Error loading preferences: \(error)")
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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.dnsSettings = blocklist.settings
|
||||
manager.localizedDescription = blocklist.description
|
||||
|
||||
do {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue