1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
import CloudKit
import Foundation
import SwiftUI
import UIKit
struct CloudSharingSheet: UIViewControllerRepresentable {
@Environment(\.dismiss) private var dismiss
let entity: ShareableEntity
let title: String
func makeCoordinator() -> Coordinator {
Coordinator(dismiss: dismiss, title: title)
}
func makeUIViewController(context _: Context) -> UIViewController {
UIViewController()
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
context.coordinator.presentIfNeeded(from: uiViewController, entity: entity)
}
final class Coordinator: NSObject, UIAdaptivePresentationControllerDelegate {
private let dismissAction: DismissAction
private let title: String
private let observer = CKSystemSharingUIObserver(container: .default())
private var hasPresented = false
init(dismiss: DismissAction, title: String) {
self.dismissAction = dismiss
self.title = title
super.init()
observer.systemSharingUIDidSaveShareBlock = { _, _ in
Task { @MainActor in
await CloudSyncService.shared.syncNow(trigger: .manual)
}
}
observer.systemSharingUIDidStopSharingBlock = { _, _ in
Task { @MainActor in
await CloudSyncService.shared.syncNow(trigger: .manual)
}
}
}
func presentIfNeeded(from presenter: UIViewController, entity: ShareableEntity) {
guard !hasPresented else { return }
hasPresented = true
let itemProvider = NSItemProvider()
let container = CKContainer.default()
Task { @MainActor in
do {
if let existingShare = try await CloudSyncService.shared.existingShare(for: entity) {
itemProvider.registerCKShare(existingShare, container: container)
} else {
itemProvider.registerCKShare(container: container) {
try await CloudSyncService.shared.createShare(for: entity)
}
}
} catch {
dismissAction()
return
}
let configuration = UIActivityItemsConfiguration(itemProviders: [itemProvider])
let activityController = UIActivityViewController(activityItemsConfiguration: configuration)
activityController.completionWithItemsHandler = { [dismissAction] _, _, _, _ in
dismissAction()
}
activityController.popoverPresentationController?.sourceView = presenter.view
activityController.presentationController?.delegate = self
presenter.present(activityController, animated: true)
}
}
func presentationControllerDidDismiss(_: UIPresentationController) {
dismissAction()
}
}
}
|