Reputation: 1588
I have the following code to import the UICloudSharingController into swift UI but when integrated the first time up it just shows an activity indicator that never stops and then the second time it is presented (via .sheet), there is no activity indicator. The first time up I can see the close button to the top right corder with activity indicator. Any feedback would be appreciated.
struct CloudSharingController: UIViewControllerRepresentable {
typealias UIViewControllerType = UICloudSharingController
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, UICloudSharingControllerDelegate {
func cloudSharingController(_ csc: UICloudSharingController, failedToSaveShareWithError error: Error) {
print("asdf")
}
func itemTitle(for csc: UICloudSharingController) -> String? {
return "item title for sharing TTT"
}
var parent: CloudSharingController
init(_ cloudSharingController: CloudSharingController) {
self.parent = cloudSharingController
}
}
var share: CKShare? = nil
var container: CKContainer = CKContainer.default()
var firsTimeBlock: ((UICloudSharingController, @escaping (CKShare?, CKContainer?, Error?) -> Void) -> Void)? = nil
func makeUIViewController(context: UIViewControllerRepresentableContext<CloudSharingController>) -> CloudSharingController.UIViewControllerType {
let result: UICloudSharingController!
if let validFirstBlock = firsTimeBlock {
return UICloudSharingController(preparationHandler: validFirstBlock)
} else if let validShare = self.share {
return UICloudSharingController(share: validShare,
container: container)
} else {
fatalError()
}
result.availablePermissions = [.allowReadWrite]
// result.popoverPresentationController?.sourceView = AccountsView
result.delegate = context.coordinator
return result
}
func updateUIViewController(_ uiViewController: CloudSharingController.UIViewControllerType, context: UIViewControllerRepresentableContext<CloudSharingController>) {
}
}
Upvotes: 8
Views: 924
Reputation: 15237
There is now a new Apple demo project that uses the UICloudSharingController
.
If no share record exists, the UICloudSharingController
is initialized with a preparationHandler
:
private func newSharingController(unsharedPhoto: Photo, persistenceController: PersistenceController) -> UICloudSharingController {
return UICloudSharingController { (_, completion: @escaping (CKShare?, CKContainer?, Error?) -> Void) in
self.persistentContainer.share([unsharedPhoto], to: nil) { objectIDs, share, container, error in
if let share = share {
self.configure(share: share)
}
completion(share, container, error)
}
}
}
where the persistenceController
is
class PersistenceController: NSObject, ObservableObject {
// …
}
The UICloudSharingController
is presented using
func presentCloudSharingController(photo: Photo) {
/**
Grab the share if the photo is already shared.
*/
var photoShare: CKShare?
if let shareSet = try? persistentContainer.fetchShares(matching: [photo.objectID]),
let (_, share) = shareSet.first {
photoShare = share
}
let sharingController: UICloudSharingController
if photoShare == nil {
sharingController = newSharingController(unsharedPhoto: photo, persistenceController: self)
} else {
sharingController = UICloudSharingController(share: photoShare!, container: cloudKitContainer)
}
sharingController.delegate = self
/**
Setting the presentation style to .formSheet so there's no need to specify sourceView, sourceItem, or sourceRect.
*/
if let viewController = rootViewController {
sharingController.modalPresentationStyle = .formSheet
viewController.present(sharingController, animated: true)
}
}
The last lines in this code show that the controller is not presented using SwiftUI, but the UIKit.
Obviously it is currently not possible to initialize the UICloudSharingController
with preparationHandler
in SwiftUI.
Upvotes: 0
Reputation: 1588
I found a work around which could be found in here:
https://gist.github.com/arashkashi/bcffde1e35c7e406de52d9dff0127d41
The solution in brief includes a view controller wrapper which contains an instance of UICloudSharingController
as a child view controller.
UICloudSharingController
has two initialized one when there is no CKShare
and another one where you already have a CKShare
pushed to the CloudKit. I observed that the former initializer gives a never ending activity indicator. So What I did I manually pushed the share with no participants and then provided the empty share to the second initialized of UICloudSharingController
.
This is the reason why the wrapper controller should have this line:
var share: CKShare? = nil
Upvotes: 6