3

Am porting over my UIDocumentPickerViewController into SwiftUI and whether I pick a file or cancel the picker I keep getting the error:

[DocumentManager] The view service did terminate with error: Error Domain=_UIViewServiceErrorDomain Code=1 "(null)" UserInfo={Terminated=disconnect method}

I call the UIDocumentPickerViewController within my View with .sheet:

.sheet(isPresented: self.$isShowingDocumentPicker, content: {
   DocumentPickerView(isShowing: $isShowingDocumentPicker, xFile: $xFile)
})

Here is a the code included into a fully runnable sample:

    import SwiftUI
    import UniformTypeIdentifiers
    
    struct ContentView: View {
        @State var isShowingDocumentPicker = false
        @State var xFile = XFile()
        
        var body: some View {
            Button {
                isShowingDocumentPicker = true
            }
            label: {
                Text("Select File")
            }
            .sheet(isPresented: self.$isShowingDocumentPicker, content: {
                            DocumentPickerView(isShowing: $isShowingDocumentPicker, xFile: $xFile)
                            })
//even using .fileImporter below in place of .sheet still produces the same error

//.fileImporter(
//            isPresented: $isShowingDocumentPicker,
//            allowedContentTypes: [.spreadsheet, .commaSeparatedText]) { result in
//            switch result {
//            case .success(let file):
//                print(file.absoluteString)
//            case .failure(let error):
//                print(error.localizedDescription)
//            }
        }
        
    }
    
    struct XFile {
        var fileName    : String
        let supportedTypes: [UTType] = [.text]
        var fullPath    : String
        
        init () {
            fileName = "no file selected"
            fullPath = ""
        }
    }
    
    struct DocumentPickerView: UIViewControllerRepresentable {
        @Binding var isShowing: Bool
        @Binding var xFile: XFile
        
        func makeUIViewController(context: Context) -> some UIViewController {
            let pickerViewController = UIDocumentPickerViewController(forOpeningContentTypes: xFile.supportedTypes)
            pickerViewController.allowsMultipleSelection = false
            pickerViewController.shouldShowFileExtensions = false
            pickerViewController.delegate = context.coordinator
            return pickerViewController
        }
        
        func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
            print ("in updater")
        }
        
        func makeCoordinator() -> Coordinator {
            Coordinator(isShowing: $isShowing, xFile: $xFile)
        }
        
        class Coordinator: NSObject, UIDocumentPickerDelegate {
            @Binding var isShowing: Bool
            @Binding var xFile: XFile
            
            init(isShowing: Binding<Bool>, xFile: Binding<XFile>) {
                _isShowing = isShowing
                _xFile      = xFile
            }
            
            func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
                
                for url in urls {
                    guard url.startAccessingSecurityScopedResource() else {
                        print ("error")
                        return
                    }
                    
                    
                    if let fileAttributes = try? FileManager.default.attributesOfItem(atPath: url.path) {
                        if let bytes = fileAttributes[.size] as? Int64 {
                            if bytes > 2048000 {
                                print ("too big")
                            } else {
                                xFile.fullPath = url.absoluteString
                                xFile.fileName = url.lastPathComponent
                            }
                        }
                    }
                    do { url.stopAccessingSecurityScopedResource() }
                }
                print ("\(xFile.fileName)")
                controller.dismiss(animated: true)
                isShowing = false
            }
            
            func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
                print("Document picker was cancelled")
                //controller.dismiss(animated: false)
                // Dismiss the document picker
                isShowing = false
            }
        }
    }

This error occurs on both the simulator as well as my physical iPhone 13.

I've tried commenting out controller.dismiss, but that makes no difference.

Is this an error I can ignore? And if not, what am I missing?

2
  • Show a minimal reproducible code that produces your issue, see: minimal code. Specifically, show the code of the view where you have your .sheet(isPresented: ...) and how you set the xFile Commented May 31, 2023 at 3:01
  • 1
    @workingdogsupportUkraine Updated OP to include minimal code. Commented May 31, 2023 at 22:35

1 Answer 1

1

Use [fileImporter][1] instead of trying to wrap UIDocumentPicker yourself. [1]: https://developer.apple.com/documentation/swiftui/form/fileimporter(ispresented:allowedcontenttypes:allowsmultipleselection:oncompletion:)?cmdf=fileImporter%20swiftui

Sign up to request clarification or add additional context in comments.

1 Comment

Replaced .sheet with .fileImporter and I get the same error. Updating OP to show both methods.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.