skip to Main Content

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) {
  }
}

2

Answers


  1. Chosen as BEST ANSWER

    I submitted a TSI about this; Apple confirmed that SWCollaborationView is not compatible with SwiftUI at the moment and we should submit feedback.


  2. In SwiftUi it’s called ShareLink

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search