SWCollaborationView was introduced as a standard UI element to manage real-time collaboration between users in iOS16+. This is explained in this Apple article. Similarly to UICloudSharingController, it's way to view participants to a share and manage sharing.
Given that UICloudSharingController is broken in iOS16+ (see this), how can I use SWCollaborationView in SwiftUI?
My failed attempts so far:
The the WWDC22 talk introducing SWCollaborationView, the speaker embedded SWCollaborationView in UIBarButtonItem(customView:). I was not able to embed UIBarButtonItem(customView:) into my SwiftUI lifecycle app, because UIBarButtonItem does not conform to UIView and therefore cannot be introduced using UIViewRepresentable.
I also tried wrapping SWCollaborationView in UIViewRepresentable and introducing it directly. The result was identical to this post. When I wrapped it in ToolbarItem, the icon appeared but no action happened on tap. When I wrapped it in ToolbarItem and Button that would open an identical collaboration view as a popover, the icon appeared (screenshot1) and on tap opened a popover where the same icon would appear (screenshot2. Only a second tap would correctly open the desired popover inherent to SWCollaborationView (screenshot3). The code for this is below.
import SwiftUI
import CloudKit
import SharedWithYou
struct DetailView: View {
var photo: Photo // some object saved in CloudKit, in this example a photo
@State var showPopover = false
@Binding var activeCover: ActiveCover? // for dismissal (not relevant for SWCollaborationView)
var body: some View {
NavigationView {
VStack {
Text("Some content of detail view")
}
.toolbar {
if let existingShare = PersistenceController.shared.existingShare(photo: photo) { // get the existing CKShare for this object (in this case we use NSPersistentCloudKitContainer.fetchShares, but that's not really relevant)
ToolbarItem(placement: .automatic) {
Button(action: {
showPopover.toggle()
}){
CollaborationView(existingShare: existingShare) // <- icon appears, but without the number of participants
}
.popover(isPresented: $showPopover) {
CollaborationView(existingShare: existingShare) // <- icon appears AGAIN, with the number of participants. Instead, we want a popover inherent to SWCollabroationView!
}
}
}
ToolbarItem(placement: .automatic) {
Button("Dismiss") { activeCover = nil }
}
}
}
}
}
struct CollaborationView: UIViewRepresentable {
let existingShare: CKShare
func makeUIView(context: Context) -> SWCollaborationView {
let itemProvider = NSItemProvider()
itemProvider.registerCKShare(existingShare,
container: PersistenceController.shared.cloudKitContainer,
allowedSharingOptions: .standard)
let collaborationView = SWCollaborationView(itemProvider: itemProvider)
collaborationView.activeParticipantCount = existingShare.participants.count
return collaborationView
}
func updateUIView(_ uiView: SWCollaborationView, context: Context) {
}
}