krz/domain-dig
an ios app for DNS & SSL analysis
clone: git clone https://gitbay.org/krz/domain-dig.git
v4.9.0: 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}