cloud-dns-ios/dns/BlockedCount.swift

80 lines
1.9 KiB
Swift
Raw Normal View History

2026-04-13 14:18:42 +01:00
import SwiftUI
import Foundation
struct BlockedCount: View {
@EnvironmentObject
private var viewModel: ViewModel
@State private var txtRecord: String = ""
2026-04-13 14:18:42 +01:00
private static let startIndex = 44
private static let formatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
return formatter
}()
2026-04-13 14:18:42 +01:00
var body: some View {
Text(txtRecord)
.onAppear {
fetchTXTRecord()
}
.onChange(of: viewModel.blocklist) { _ in
fetchTXTRecord()
}
2026-04-13 14:18:42 +01:00
}
func parseResponse(data: Data) -> String? {
// This is a DNS wire format response and we make a lot of assumptions
// It is not critical functionality so just let it fail if it fails
guard data.count > Self.startIndex else {
return nil
2026-04-13 14:18:42 +01:00
}
// Find the first space character (ASCII 32).
guard let endIndex = data.suffix(from: Self.startIndex).firstIndex(of: 32) else {
return nil
}
2026-04-13 14:18:42 +01:00
guard let numberString = String(data: data[Self.startIndex ..< endIndex], encoding: .utf8)
else {
return nil
}
2026-04-13 14:18:42 +01:00
return Self.formatter.string(for: Int(numberString))
2026-04-13 14:18:42 +01:00
}
func fetchTXTRecord() {
let dohURL = URL(string: "https://\(viewModel.blocklist.server)/dns-query?dns=DoQBAAABAAAAAAAABXN0YXRzB2ludmFsaWQAABAAAQ")!
2026-04-13 14:18:42 +01:00
let request = URLRequest(url: dohURL)
txtRecord = ""
Task {
do {
let (data, _) = try await URLSession.shared.data(for: request)
2026-04-13 14:18:42 +01:00
if let count = parseResponse(data: data) {
txtRecord = count
2026-04-13 14:18:42 +01:00
}
else {
2026-04-13 14:18:42 +01:00
txtRecord = "Error"
}
}
catch {
txtRecord = "Error"
}
}
2026-04-13 14:18:42 +01:00
}
}
#Preview {
BlockedCount()
.environmentObject(ViewModel())
2026-04-13 14:18:42 +01:00
}