Can't see how to use UIActivityViewController

Basically I've tried to wrap it using UIViewControllerRepresentable, and in doing that I have to specify what to share in the makeUIViewController method, which is called only once the first time the entire view is rendered. After that only calls to updateUIViewController are provided, and there is no way to update the data in the UIActivityViewController.


Here's how I wrapped it:


struct SwiftUIActivityView: UIViewControllerRepresentable, Identifiable {
    var id = UUID()
   
    @Binding var text: String
   
    func makeUIViewController(context: Context) -> UIActivityViewController {
        print("*** makeUIViewController: \(id) ***")
       
        let result = UIActivityViewController(activityItems: [text], applicationActivities: nil)
       
        result.completionWithItemsHandler = { (activityType, completed, returnedItems, error) in
            if completed {
                print("*** completed ***")
            } else {
                print("*** not completed ***")
            }
        }
       
        return result
    }
   
    func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {
    }
   
}


Here's how I used it (in a sheet). This method tried to force a reallocation of my wrapper everytime in hopes that would flesh things out, but it didn't. The code:


struct WrappedUIActivityView: View {
    @State private var message = "a message"
    @State private var sheetToShow: SwiftUIActivityView?
   
    var body: some View {
        VStack {
            TextField("what to share", text: $message)
           
            Button("Share") {
                self.sheetToShow = SwiftUIActivityView(text: self.$message)
            }
           
            Spacer()
        }
        .padding()
        .sheet(item: $sheetToShow) { something in
            self.sheetToShow
        }
    }
}


Using UIActivityItemSource (god I wish that pasting in this field didn't move the cursor to the top left) or UIActivityItemProvider makes no difference. If anything, they are worse since the placeholders don't show.


The only thing that works is to put all this in a NavigationView, get the view above pushed on the stack, then hitting the back button and tapping again. That gets another one time use of the sheet.


This is using Xcode labled as beta 7 on the developer portal but that shows beta 6 in its about box -- 11M392r


Breaks the major feature in the dirt simple app I was converting over if it can't share. :-(

I think this might be related to trying to present my wrapped view in a sheet where that sheet is itself presenting a sheet itself, and in the end only one of them really goes away. I reworked it using a custom ViewController that presents the UIActivityViewController when it loads. This extra level of indirection allows me to update the text that will be shown using updateUIViewController, but it also allows me to reuse the view each time.


Here's what I did:


class UIActivityViewControllerHost: UIViewController {
    var message = ""
    var completionWithItemsHandler: UIActivityViewController.CompletionWithItemsHandler? = nil
   
    override func viewDidAppear(_ animated: Bool) {
        share()
    }
   
    func share() {
        // set up activity view controller
        let textToShare = [ message ]
        let activityViewController = UIActivityViewController(activityItems: textToShare, applicationActivities: nil)


        activityViewController.completionWithItemsHandler = completionWithItemsHandler
        activityViewController.popoverPresentationController?.sourceView = self.view // so that iPads won't crash


        // present the view controller
        self.present(activityViewController, animated: true, completion: nil)
    }
}


struct ActivityViewController: UIViewControllerRepresentable {
    @Binding var text: String
    @Binding var showing: Bool
   
    func makeUIViewController(context: Context) -> UIActivityViewControllerHost {
        // Create the host and setup the conditions for destroying it
        let result = UIActivityViewControllerHost()
       
        result.completionWithItemsHandler = { (activityType, completed, returnedItems, error) in
            // To indicate to the hosting view this should be "dismissed"
            self.showing = false
        }
       
        return result
    }
   
    func updateUIViewController(_ uiViewController: UIActivityViewControllerHost, context: Context) {
        // Update the text in the hosting controller
        uiViewController.message = text
    }
   
}


struct ContentView: View {
    @State private var showSheet = false
    @State private var message = "a message"
   
    var body: some View {
        VStack {
            TextField("what to share", text: $message)
           
            Button("Hello World") {
                self.showSheet = true
            }
           
            if showSheet {
                ActivityViewController(text: $message, showing: $showSheet)
                    .frame(width: 0, height: 0)
            }
           
            Spacer()
        }
        .padding()
    }
}
Can't see how to use UIActivityViewController
 
 
Q