summaryrefslogtreecommitdiff
path: root/DomainDig/CloudSharingSheet.swift
diff options
context:
space:
mode:
Diffstat (limited to 'DomainDig/CloudSharingSheet.swift')
-rw-r--r--DomainDig/CloudSharingSheet.swift84
1 files changed, 84 insertions, 0 deletions
diff --git a/DomainDig/CloudSharingSheet.swift b/DomainDig/CloudSharingSheet.swift
new file mode 100644
index 0000000..3d524ef
--- /dev/null
+++ b/DomainDig/CloudSharingSheet.swift
@@ -0,0 +1,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(_ presentationController: UIPresentationController) {
+ dismissAction()
+ }
+ }
+}