4

I use the didPickDocumentAt function to retrieve the url of the picked file in the DocumentPickerViewController. I have a multipart upload function that uses alamofire to upload files to the backend.

func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
    print(url)
    uploadMultipartFile()
}

My question is: How can I get a data representation of the file I have picked so I can pass it to my uploadMultipartFile function?

The Files can be pdf, .docx, or any kind of file. What is the approach?

Jochen Österreicher
  • 683
  • 2
  • 11
  • 25

2 Answers2

8

Have a look at dataWithContentsOfURL:

Returns a data object containing the data from the location specified by a given URL.

Note that it throws if it cannot create the data representation from the URL.

So in your case maybe something like this:

func documentPicker(_ controller: UIDocumentPickerViewController, 
      didPickDocumentsAt urls: [URL]) {
print(url)
    do {
        var documentData = [Data]()
        for url in urls {
            documentData.append(try Data(contentsOf: url))
        }

        //hopefully you have an array of data elements now :)                
        uploadMultipartFile()
    } catch {
        print("no data")
    }
}

Hope that helps.

pbodsk
  • 6,787
  • 3
  • 21
  • 51
  • 1
    url is not optional and btw single url method is deprecated. you should use `documentPicker(_:didPickDocumentsAt:)` https://developer.apple.com/documentation/uikit/uidocumentpickerdelegate/2902364-documentpicker – Leo Dabus Mar 25 '18 at 20:00
  • @LeoDabus Sorry, you're right (it was in my playground example, thats why :)) Thanks for the catch, I've fixed it now. – pbodsk Mar 25 '18 at 20:02
  • Thank you so far but one more question, I remember having read about the files being sandboxed and that it is needed to do more to access them. Is that still true? – Jochen Österreicher Mar 25 '18 at 20:10
  • 1
    I’m actually not sure to be honest. I mean...your files are sandboxed yes, but that should allow you to access them. Also, if you look here: https://developer.apple.com/library/content/documentation/FileManagement/Conceptual/DocumentPickerProgrammingGuide/Introduction/Introduction.html there is a section about “Accessing Files Outside Your Sandbox” so that seems possible as well...just takes a little work. Sorry for the vague reply. – pbodsk Mar 25 '18 at 20:20
2

For me it didn't work. What worked:

func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
    guard
        let url = urls.first,
        url.startAccessingSecurityScopedResource()
    else {
            return
    }
    defer { url.stopAccessingSecurityScopedResource() }
    do {
        let data = try Data(contentsOf: url)
        print(data)
        //DO SMTH WITH YOUR DATA
    } catch {
            print(error)
    }
}

Apparently that's due to security restrictions you need to have security bookmark to access file.

Shalugin
  • 1,092
  • 2
  • 10
  • 15