Compare commits
5 commits
9f30f9f686
...
634b4d26e8
| Author | SHA1 | Date | |
|---|---|---|---|
| 634b4d26e8 | |||
| 6b253a6843 | |||
| 3ec25bc247 | |||
| 9d016eea17 | |||
| 9d78a3aacf |
8 changed files with 147 additions and 95 deletions
|
|
@ -8,6 +8,9 @@
|
|||
|
||||
/* Begin PBXFileReference section */
|
||||
069DCCFA2F8C0DCE00F1EB16 /* dns.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = dns.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A06A74772F8E95410093A9E4 /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = "<group>"; };
|
||||
A06A74782F8E95410093A9E4 /* LICENCE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENCE; sourceTree = "<group>"; };
|
||||
A06A74792F8E95410093A9E4 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
||||
|
|
@ -32,6 +35,9 @@
|
|||
069DCCF12F8C0DCD00F1EB16 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A06A74772F8E95410093A9E4 /* .gitignore */,
|
||||
A06A74782F8E95410093A9E4 /* LICENCE */,
|
||||
A06A74792F8E95410093A9E4 /* README.md */,
|
||||
069DCCFC2F8C0DCE00F1EB16 /* dns */,
|
||||
069DCCFB2F8C0DCE00F1EB16 /* Products */,
|
||||
);
|
||||
|
|
@ -251,6 +257,7 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_ENTITLEMENTS = dns/dns.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
|
|
@ -262,6 +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;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
|
@ -285,6 +293,7 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_ENTITLEMENTS = dns/dns.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
|
|
@ -296,6 +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;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,10 @@ import Foundation
|
|||
|
||||
struct BlockedCount: View {
|
||||
|
||||
@State private var txtRecord: String = "..."
|
||||
@EnvironmentObject
|
||||
private var viewModel: ViewModel
|
||||
|
||||
@State private var txtRecord: String = "…"
|
||||
|
||||
private static let startIndex = 44
|
||||
|
||||
|
|
@ -44,33 +47,29 @@ struct BlockedCount: View {
|
|||
}
|
||||
|
||||
func fetchTXTRecord() {
|
||||
let dohURL = URL(string: "https://dns.sr2.uk/dns-query?dns=DoQBAAABAAAAAAAABXN0YXRzB2ludmFsaWQAABAAAQ")!
|
||||
let dohURL = URL(string: "https://\(viewModel.blocklist.server)/dns-query?dns=DoQBAAABAAAAAAAABXN0YXRzB2ludmFsaWQAABAAAQ")!
|
||||
|
||||
let request = URLRequest(url: dohURL)
|
||||
|
||||
URLSession.shared.dataTask(with: request) { data, response, error in
|
||||
DispatchQueue.main.async {
|
||||
if error != nil {
|
||||
txtRecord = "Error"
|
||||
return
|
||||
}
|
||||
Task {
|
||||
do {
|
||||
let (data, _) = try await URLSession.shared.data(for: request)
|
||||
|
||||
guard let data = data else {
|
||||
txtRecord = "Error"
|
||||
return
|
||||
if let count = parseResponse(data: data) {
|
||||
txtRecord = count
|
||||
}
|
||||
|
||||
guard let count = parseResponse(data: data) else {
|
||||
else {
|
||||
txtRecord = "Error"
|
||||
return
|
||||
}
|
||||
|
||||
txtRecord = count
|
||||
}
|
||||
}.resume()
|
||||
catch {
|
||||
txtRecord = "Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
BlockedCount()
|
||||
.environmentObject(ViewModel())
|
||||
}
|
||||
|
|
|
|||
69
dns/BlocklistOption.swift
Normal file
69
dns/BlocklistOption.swift
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
//
|
||||
// BlocklistOption.swift
|
||||
// dns
|
||||
//
|
||||
// Created by Benjamin Erhart on 14.04.26.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum BlocklistOption: String, CaseIterable, Identifiable {
|
||||
case secure = "Secure"
|
||||
case securePlusAdblock = "Secure + Adblock"
|
||||
|
||||
var id: String { rawValue }
|
||||
|
||||
var enabled: Bool {
|
||||
switch self {
|
||||
case .secure:
|
||||
return true
|
||||
case .securePlusAdblock:
|
||||
return true //false
|
||||
}
|
||||
}
|
||||
|
||||
var description: String {
|
||||
switch self {
|
||||
case .secure:
|
||||
return "Malware and phishing protection"
|
||||
case .securePlusAdblock:
|
||||
return "Security plus ad and tracker blocking"
|
||||
}
|
||||
}
|
||||
|
||||
var icon: String {
|
||||
switch self {
|
||||
case .secure:
|
||||
return "shield"
|
||||
case .securePlusAdblock:
|
||||
return "shield.righthalf.filled"
|
||||
}
|
||||
}
|
||||
|
||||
var server: String {
|
||||
switch self {
|
||||
case .secure:
|
||||
return "dns.sr2.uk"
|
||||
case .securePlusAdblock:
|
||||
return "dnsplus.sr2.uk"
|
||||
}
|
||||
}
|
||||
|
||||
var ipv4: String {
|
||||
switch self {
|
||||
case .secure:
|
||||
return "144.76.160.194"
|
||||
case .securePlusAdblock:
|
||||
return "192.0.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
var ipv6: String {
|
||||
switch self {
|
||||
case .secure:
|
||||
return "2a01:4f8:2210:23ea::4"
|
||||
case .securePlusAdblock:
|
||||
return "2001:db8::1"
|
||||
}
|
||||
}
|
||||
}
|
||||
16
dns/DnsApp.swift
Normal file
16
dns/DnsApp.swift
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
import SwiftUI
|
||||
|
||||
@main
|
||||
struct DnsApp: App {
|
||||
|
||||
@StateObject
|
||||
var viewModel = ViewModel()
|
||||
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
HomeView()
|
||||
.environmentObject(viewModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,67 +1,6 @@
|
|||
|
||||
import SwiftUI
|
||||
|
||||
enum BlocklistOption: String, CaseIterable, Identifiable {
|
||||
case secure = "Secure"
|
||||
case securePlusAdblock = "Secure + Adblock"
|
||||
|
||||
var id: String { rawValue }
|
||||
|
||||
var enabled: Bool {
|
||||
switch self {
|
||||
case .secure:
|
||||
return true
|
||||
case .securePlusAdblock:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
var description: String {
|
||||
switch self {
|
||||
case .secure:
|
||||
return "Malware and phishing protection"
|
||||
case .securePlusAdblock:
|
||||
return "Security plus ad and tracker blocking"
|
||||
}
|
||||
}
|
||||
|
||||
var icon: String {
|
||||
switch self {
|
||||
case .secure:
|
||||
return "shield"
|
||||
case .securePlusAdblock:
|
||||
return "shield.righthalf.filled"
|
||||
}
|
||||
}
|
||||
|
||||
var server: String {
|
||||
switch self {
|
||||
case .secure:
|
||||
return "dns.sr2.uk"
|
||||
case .securePlusAdblock:
|
||||
return "dnsplus.sr2.uk"
|
||||
}
|
||||
}
|
||||
|
||||
var ipv4: String {
|
||||
switch self {
|
||||
case .secure:
|
||||
return "144.76.160.194"
|
||||
case .securePlusAdblock:
|
||||
return "192.0.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
var ipv6: String {
|
||||
switch self {
|
||||
case .secure:
|
||||
return "2a01:4f8:2210:23ea::4"
|
||||
case .securePlusAdblock:
|
||||
return "2001:db8::1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum ServiceStatus {
|
||||
case pending
|
||||
case operational
|
||||
|
|
@ -96,8 +35,11 @@ enum ServiceStatus {
|
|||
}
|
||||
|
||||
struct HomeView: View {
|
||||
|
||||
@EnvironmentObject
|
||||
private var viewModel: ViewModel
|
||||
|
||||
@State private var isEnabled = false
|
||||
@State private var selectedBlocklist: BlocklistOption = .secure
|
||||
@State private var serviceStatus: ServiceStatus = .operational
|
||||
|
||||
private let falsePositiveURL = URL(string: "https://www.sr2.uk/contact")!
|
||||
|
|
@ -135,13 +77,13 @@ struct HomeView: View {
|
|||
ForEach(BlocklistOption.allCases) { option in
|
||||
BlocklistRow(
|
||||
option: option,
|
||||
isSelected: selectedBlocklist == option
|
||||
isSelected: viewModel.blocklist == option
|
||||
)
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture {
|
||||
guard option.enabled else { return }
|
||||
withAnimation(.spring(duration: 0.3)) {
|
||||
selectedBlocklist = option
|
||||
viewModel.blocklist = option
|
||||
}
|
||||
}
|
||||
.opacity(option.enabled ? 1 : 0.6)
|
||||
|
|
@ -166,7 +108,7 @@ struct HomeView: View {
|
|||
HStack {
|
||||
Label("Server", systemImage: "server.rack")
|
||||
Spacer()
|
||||
Text(selectedBlocklist.server)
|
||||
Text(viewModel.blocklist.server)
|
||||
.foregroundStyle(.secondary)
|
||||
.font(.system(.body, design: .monospaced))
|
||||
}
|
||||
|
|
@ -174,7 +116,7 @@ struct HomeView: View {
|
|||
HStack {
|
||||
Label("IPv4", systemImage: "globe")
|
||||
Spacer()
|
||||
Text(selectedBlocklist.ipv4)
|
||||
Text(viewModel.blocklist.ipv4)
|
||||
.foregroundStyle(.secondary)
|
||||
.font(.system(.body, design: .monospaced))
|
||||
}
|
||||
|
|
@ -182,7 +124,7 @@ struct HomeView: View {
|
|||
HStack {
|
||||
Label("IPv6", systemImage: "globe")
|
||||
Spacer()
|
||||
Text(selectedBlocklist.ipv6)
|
||||
Text(viewModel.blocklist.ipv6)
|
||||
.foregroundStyle(.secondary)
|
||||
.font(.system(.body, design: .monospaced))
|
||||
}
|
||||
|
|
@ -278,4 +220,5 @@ struct HomeView: View {
|
|||
|
||||
#Preview {
|
||||
HomeView()
|
||||
.environmentObject(ViewModel())
|
||||
}
|
||||
|
|
|
|||
16
dns/ViewModel.swift
Normal file
16
dns/ViewModel.swift
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
//
|
||||
// ViewModel.swift
|
||||
// dns
|
||||
//
|
||||
// Created by Benjamin Erhart on 14.04.26.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
|
||||
class ViewModel: NSObject, ObservableObject {
|
||||
|
||||
@Published
|
||||
var blocklist: BlocklistOption = .secure
|
||||
|
||||
}
|
||||
10
dns/dns.entitlements
Normal file
10
dns/dns.entitlements
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.developer.networking.networkextension</key>
|
||||
<array>
|
||||
<string>dns-settings</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
import SwiftUI
|
||||
|
||||
@main
|
||||
struct dnsApp: App {
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
HomeView()
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue