allowsMultipleSelection not working via SwiftUI

I'm trying to use UIDocumentPickerViewController from SwiftUI using UIViewControllerRepresentable. I've managed to show a file picker dialog, but it doesn't allow multiple file selection even when I set allowsMultipleSelection to true.

Is this a bug or am I doing something wrong?

Here's the code:

Code Block
import SwiftUI
import UIKit
import CoreServices
struct DocumentPicker: UIViewControllerRepresentable {
    typealias UIViewControllerType = UIDocumentPickerViewController
    func makeUIViewController(context: Context) -> UIDocumentPickerViewController {
        let picker = UIDocumentPickerViewController(documentTypes: [kUTTypeImage as String], in: .open)
        picker.allowsMultipleSelection = true
        return picker
    }
    func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: Context) { }
}


And here's the test view which triggers the picker.
Code Block
import SwiftUI
struct ContentView: View {
    @State var isPickerPresented = false
    var body: some View {
        Button("Show Picker") {
            isPickerPresented = true
        }.sheet(isPresented: $isPickerPresented) {
            DocumentPicker()
        }
    }
}


Answered by yohki1 in 620123022
Finally it worked on my iPad too after updating to iPadOS/Xcode beta 2.
Actually it didn't work on the first try, then I added one line inside updateUIViewController, and now it works!

Code Block language
    func makeUIViewController(context: Context) -> UIDocumentPickerViewController {
        let picker = UIDocumentPickerViewController(documentTypes: [kUTTypeImage as String], in: .open)
        picker.allowsMultipleSelection = true
        return picker
    }
    func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: Context) {
        uiViewController.allowsMultipleSelection = true
    }


The weird thing is it still works correctly even after I remove the line in updateUIViewController...
Anyway, thanks for your help @OOPer and @marlonjames.

As far as I tried your code on Xcode 11.5 and 12 beta, a picker with Select or circled ... appeared and with tapping Select, I could choose multiple files.

(I needed to add self. to line 9 of your ContentView in Xcode 11.5, but that may not be a big issue.)

Can you describe your testing environment?
@OOper thanks for testing.

My development environment is:
  • macOS 11.0 Beta

  • Xcode 12.0 Beta

  • iPad Pro (2nd Gen) + iPadOS 14.0 Beta


My development environment is:

Thanks for showing your environment.
Frankly, I cannot prepare the same environment, but hope someone can re-test your code and reveal what's happening.
I was forgetting that I could test it with iPad simulator.

And I could have confirmed that the picker did not have Select only when shown in SwiftUI with your code with Xcode 12 beta.

I'm afraid this is a bug of iPadOS 14.
I tested with my iPhone XS + iOS 13.5.1, which worked fine.
Like you said, It's highly likely that it's a bug of iOS 14.
Thanks again for your help.
You can send a feedback about this issue through Feedback Assistant.
Hoping this issue will be fixed soon.
It may be because you're not setting the delegate? If you need to set the delegate you need to use a coordinator of some sort. This is what I'm using and it's working:

Code Block swift
struct DocumentPickerView: UIViewControllerRepresentable {
var onComplete: ([URL], MimeType) -> Void
func makeCoordinator() -> DocPickerCoordinator {
DocPickerCoordinator(docParent: self)
}
func makeUIViewController(context: UIViewControllerRepresentableContext<DocumentPickerView>) -> UIDocumentPickerViewController {
let picker = UIDocumentPickerViewController(documentTypes: [.pdfType], in: .import)
picker.allowsMultipleSelection = true
picker.delegate = context.coordinator
return picker
}
func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: UIViewControllerRepresentableContext<DocumentPickerView>) {}
}
class DocPickerCoordinator: NSObject, UIDocumentPickerDelegate {
private var parent: DocumentPickerView
init(docParent: DocumentPickerView) {
parent = docParent
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
parent.onComplete(urls, .pdf)
}
}
extension String {
static let pdfType = kUTTypePDF as Self
}


I hope this helps!
@marlonjames 

Thanks for showing your code. I did not expect setting delegate would change the behavior.

May I ask you one question?
When I test your code in iPad simulator from Xcode 12 while the simulator is not running, your code works as expected and the picker show Select.
But if I run the testing app while the simulator is running, the picker does not show Select.

Do you think this is just a problem of simulator?
Seems this issue is fixed in Xcode 12 beta 2.
Whether setting delegate or not, whether while simulator is running or not,
iPadOS simulator shows the right picker with setting .allowsMultipleSelection = true.
Accepted Answer
Finally it worked on my iPad too after updating to iPadOS/Xcode beta 2.
Actually it didn't work on the first try, then I added one line inside updateUIViewController, and now it works!

Code Block language
    func makeUIViewController(context: Context) -> UIDocumentPickerViewController {
        let picker = UIDocumentPickerViewController(documentTypes: [kUTTypeImage as String], in: .open)
        picker.allowsMultipleSelection = true
        return picker
    }
    func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: Context) {
        uiViewController.allowsMultipleSelection = true
    }


The weird thing is it still works correctly even after I remove the line in updateUIViewController...
Anyway, thanks for your help @OOPer and @marlonjames.

There is an alternative to using UIDocumentPickerViewController so you don't have to incorporate UIKit in the picker.

There's a new importFilesAction:

Code Block swift
importFiles(multipleOfType: [_Array of UTType_])


Code Block swift
import SwiftUI
struct ContentView: View {
@Environment(\.importFiles) var importFiles
var body: some View {
Button("Show Picker") {
importFiles(singleOfType: [.plainText]) { result in
switch result {
case .success(let url):
print("Success! \(url)")
case .failure(let error):
print("Error: \(error.localizedDescription)")
case .none:
print("Cancelled")
}
}
}
}
}

@BabyJ I tried your solution, but I can't seem to get the bookmark, do you know what's cracking?

edit: The issue seems to be me, the file doesn't exist anymore, according to this error:
Code Block swift
Error Domain=NSCocoaErrorDomain Code=260 "The file couldn’t be opened because it doesn’t exist."

allowsMultipleSelection not working via SwiftUI
 
 
Q