krz/domain-dig

an ios app for DNS & SSL analysis

clone: git clone https://gitbay.org/krz/domain-dig.git

main: DomainDigShareExtension/ShareViewController.swift · raw

 1import UIKit
 2import UniformTypeIdentifiers
 3
 4/// Receives a web URL from the share sheet, extracts its host, and hands it to
 5/// the app through the App Group inbox. Shows a brief confirmation and closes;
 6/// the app picks up the domain the next time it becomes active.
 7final class ShareViewController: UIViewController {
 8    private let label = UILabel()
 9
10    override func viewDidLoad() {
11        super.viewDidLoad()
12        view.backgroundColor = .systemBackground
13
14        label.text = "Saving…"
15        label.font = .preferredFont(forTextStyle: .headline)
16        label.textAlignment = .center
17        label.numberOfLines = 0
18        label.translatesAutoresizingMaskIntoConstraints = false
19        view.addSubview(label)
20        NSLayoutConstraint.activate([
21            label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
22            label.centerYAnchor.constraint(equalTo: view.centerYAnchor),
23            label.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor, constant: 24),
24            label.trailingAnchor.constraint(lessThanOrEqualTo: view.trailingAnchor, constant: -24)
25        ])
26
27        // Task inherits this view controller's MainActor context, so finish()
28        // lands back on main without a manual dispatch. The continuation form
29        // also avoids sending a non-Sendable completion into loadItem's
30        // @Sendable handler. (#27)
31        Task { [weak self] in
32            let domain = await self?.extractSharedDomain()
33            self?.finish(domain: domain ?? nil)
34        }
35    }
36
37    private func extractSharedDomain() async -> String? {
38        let providers = (extensionContext?.inputItems ?? [])
39            .compactMap { $0 as? NSExtensionItem }
40            .flatMap { $0.attachments ?? [] }
41
42        guard let provider = providers.first(where: {
43            $0.hasItemConformingToTypeIdentifier(UTType.url.identifier)
44        }) else {
45            return nil
46        }
47
48        return await withCheckedContinuation { continuation in
49            provider.loadItem(forTypeIdentifier: UTType.url.identifier) { item, _ in
50                let url = item as? URL ?? (item as? Data).flatMap { URL(dataRepresentation: $0, relativeTo: nil) }
51                let host = url?.host?.trimmingCharacters(in: .whitespacesAndNewlines)
52                continuation.resume(returning: host?.isEmpty == false ? host : nil)
53            }
54        }
55    }
56
57    private func finish(domain: String?) {
58        if let domain {
59            DomainDigShareInbox.write(domain: domain)
60            label.text = "Saved \(domain) — open DomainDig to inspect it."
61        } else {
62            label.text = "No web address found."
63        }
64
65        DispatchQueue.main.asyncAfter(deadline: .now() + 1.4) { [weak self] in
66            self?.extensionContext?.completeRequest(returningItems: nil)
67        }
68    }
69}