'UIDocumentPickerViewController in SwiftUI on mac (macCatalyst)

So I've been meddling with "moving" a small SwiftUI iPad app to the Mac, and I've hit a bit of a speed bump with UIDocumentPickerViewController. I have wrapped the UIDocumentPickerViewController in a UIViewControllerRepresentable like so :

struct DocumentPickerView: UIViewControllerRepresentable {
  func makeUIViewController(context: Context) -> UIDocumentPickerViewController {
    let documentPicker = UIDocumentPickerViewController(documentTypes: [(kUTTypeImage as String)], in: .import)
    return documentPicker
  }

  func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: Context) {

  }
}

And displaying it like this:

struct ContentView: View {
@State var shows = false
var body: some View {
    Button(action: { self.shows.toggle() }) {
        Text("Select File")
    }
    .sheet(isPresented: self.$shows) {
        DocumentPickerView()
    }
  }
}

On the iPad all is working well, iPad

But when on on the Mac, the UIDocumentPickerViewControllerdoesnt show and we get this blank modal:

Mac



Solution 1:[1]

For some reason (I'm not aware of further specific details), the following worked for me (for Catalyst):

Instead of using in: .import

let documentPicker = UIDocumentPickerViewController(
    documentTypes: [(kUTTypeImage as String)], 
    in: .import
)

Use in: .open

let documentPicker = UIDocumentPickerViewController(
    documentTypes: [(kUTTypeImage as String)], 
    in: .open
)

I haven't checked if the functionality is maintained in iOS, but perhaps you can use some sort of "flag" to determine wether to use .import or .open

Solution 2:[2]

I replaced deprecated method and enabled asked entitlement for provided topic starter code and it works.

Tested with Xcode 13.3 / macOS 12.2

import UniformTypeIdentifiers
struct DocumentPickerView: UIViewControllerRepresentable {
  func makeUIViewController(context: Context) -> UIDocumentPickerViewController {
    let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: [UTType.image], asCopy: true)
    return documentPicker
  }

  func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: Context) {

  }
}

config

and demo opening standard macOS picker

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 charlieVader
Solution 2 Asperi