summaryrefslogtreecommitdiff
path: root/DomainDig/ContentView.swift
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-04-03 16:51:18 -0500
committerChristian Cleberg <[email protected]>2026-04-03 16:51:18 -0500
commit9c691f6c6c579a3fbb3bd5bbd74eb0e92ca0bd41 (patch)
treefb2473ad6257a4b1a1b3392d377ef6efd3291a9a /DomainDig/ContentView.swift
parentede15c586af71b8d6f2c190ffdad0324414cac06 (diff)
downloaddomain-dig-9c691f6c6c579a3fbb3bd5bbd74eb0e92ca0bd41.tar.gz
domain-dig-9c691f6c6c579a3fbb3bd5bbd74eb0e92ca0bd41.tar.bz2
domain-dig-9c691f6c6c579a3fbb3bd5bbd74eb0e92ca0bd41.zip
DomainDig 1.3.0
- Add SOA, SRV, CAA, and DS DNS record lookups - Add DNSSEC status detection via RRSIG queries - Add configurable DNS-over-HTTPS resolver settings - Support Cloudflare, Google, Quad9, and custom HTTPS resolvers - Improve DoH compatibility with standards-based fallback handling - Keep DNS results UI compact with a single DNSSEC indicator
Diffstat (limited to 'DomainDig/ContentView.swift')
-rw-r--r--DomainDig/ContentView.swift87
1 files changed, 86 insertions, 1 deletions
diff --git a/DomainDig/ContentView.swift b/DomainDig/ContentView.swift
index b6a7607..87d8a85 100644
--- a/DomainDig/ContentView.swift
+++ b/DomainDig/ContentView.swift
@@ -54,6 +54,14 @@ struct ContentView: View {
.foregroundStyle(.secondary)
}
}
+ ToolbarItem(placement: .topBarTrailing) {
+ NavigationLink {
+ SettingsView()
+ } label: {
+ Image(systemName: "gearshape")
+ .foregroundStyle(.secondary)
+ }
+ }
}
}
.onAppear {
@@ -257,7 +265,16 @@ struct ContentView: View {
private var dnsResultsSection: some View {
VStack(alignment: .leading, spacing: 12) {
- sectionHeader("DNS Records")
+ HStack(alignment: .top, spacing: 8) {
+ sectionHeader("DNS Records")
+ Spacer()
+ if let dnssecSigned = dnssecStatus {
+ Text(dnssecSigned ? "DNSSEC ✓" : "DNSSEC ✗")
+ .font(.system(.caption2, design: .monospaced))
+ .foregroundStyle(dnssecSigned ? .green : .red)
+ .padding(.top, 1)
+ }
+ }
if viewModel.dnsLoading {
ProgressView("Querying DNS…")
@@ -596,6 +613,10 @@ struct ContentView: View {
.foregroundStyle(.white)
}
+ private var dnssecStatus: Bool? {
+ viewModel.dnsSections.compactMap(\.dnssecSigned).first
+ }
+
private func certRow(_ label: String, _ value: String) -> some View {
VStack(alignment: .leading, spacing: 2) {
Text(label)
@@ -681,6 +702,70 @@ extension DateFormatter {
}()
}
+private struct SettingsView: View {
+ @AppStorage(DNSResolverOption.userDefaultsKey)
+ private var storedResolverURL = DNSResolverOption.defaultURLString
+
+ @State private var resolverOption: DNSResolverOption = .cloudflare
+ @State private var customResolverURL = DNSResolverOption.defaultURLString
+
+ private var customResolverError: String? {
+ guard resolverOption == .custom else {
+ return nil
+ }
+
+ return DNSResolverOption.isValidCustomURL(customResolverURL)
+ ? nil
+ : "Resolver URL must start with https://"
+ }
+
+ var body: some View {
+ Form {
+ Section {
+ Picker("Resolver", selection: $resolverOption) {
+ ForEach(DNSResolverOption.allCases) { option in
+ Text(option.title).tag(option)
+ }
+ }
+
+ if resolverOption == .custom {
+ TextField("https://resolver.example/dns-query", text: $customResolverURL)
+ .textInputAutocapitalization(.never)
+ .autocorrectionDisabled()
+ .keyboardType(.URL)
+
+ if let customResolverError {
+ Text(customResolverError)
+ .font(.caption)
+ .foregroundStyle(.red)
+ }
+ }
+ }
+ }
+ .navigationTitle("Settings")
+ .onAppear {
+ let currentResolverURL = storedResolverURL.trimmingCharacters(in: .whitespacesAndNewlines)
+ resolverOption = DNSResolverOption.option(for: currentResolverURL)
+ customResolverURL = resolverOption == .custom
+ ? currentResolverURL
+ : DNSResolverOption.defaultURLString
+ }
+ .onChange(of: resolverOption) { _, newValue in
+ guard let presetURL = newValue.urlString else {
+ storedResolverURL = customResolverURL.trimmingCharacters(in: .whitespacesAndNewlines)
+ return
+ }
+ storedResolverURL = presetURL
+ }
+ .onChange(of: customResolverURL) { _, newValue in
+ guard resolverOption == .custom else {
+ return
+ }
+ storedResolverURL = newValue.trimmingCharacters(in: .whitespacesAndNewlines)
+ }
+ }
+}
+
#Preview {
ContentView()
}