Icloud Drive Issue: "[Documentmanager] Failed to Associate Thumbnails for Picked Url"

why my UIDocumentPickerViewController returns me a url not reachable?

I am using UIDocumentPicker like below and it works fine:

First I have an enum,

enum UploadFileType{
case photo
case file
}

Then a structure:

struct UploadFileData {
var fileName: String
var fileType: UploadFileType
var fileData: NSData
}

var file: UploadFileData?

func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
let fileManager = FileManager.default
print(fileManager.fileExists(atPath: url.path))
let data = NSData(contentsOfFile: url.path)
guard let doc = data else {
// Utility.showAlert(message: Strings.ERROR.text, title: Strings.DOCUMENT_FORMAT_NOT_SUPPORTED.text, controller: self)
return
}
self.file = UploadFileData(fileName: "\(url)", fileType: .file, fileData: doc)
guard let dataFile = self.file?.fileData as Data? else {return}
}

Picking a Folder from iCloud with Document Picker

You are getting this error because you are getting the path of the folder in which your files exist and like @ivan-ičin has said in the comments you cannot pick an entire folder from iCloud according to the documentation.

So if you are trying to upload all the files of a specific folder to your server i would suggest you get the URL of the folder and then using the below code you can get a list all the files present in that folder.

Here is how you can get a list of all the files present in the documents folder that you are trying to pick.

let fileManager = FileManager.default
let documentsURL = "YOUR FOLDER URL"
//If all files are in your app document directory then use this line
//fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]

do {
let fileURLs = try fileManager.contentsOfDirectory(at: documentsURL, includingPropertiesForKeys: nil)
// Append files to an array here and then iterate the array later and upload files to server one by one.
} catch {
print("Error while enumerating files \(documentsURL.path): \(error.localizedDescription)")
}

Once you get the URLs you can append them to an array and upload them one by one to your server using Alamofire.

Swift IOS - How can I obtain permission to upload a document when testing on a device?

I figured it out based on an answer I found here.

What I was doing is: I was storing a reference to the local file, which is a security scoped resource. Hence the permission error was thrown.

What I did to get around this: At the moment when the user picks the file, I will use url.startAccessingSecurityScopedResource() to start accessing its content and make a copy of the file instead of holding its reference.

Here is the updated code for the picker didPickDocumentsAt:

func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard controller.documentPickerMode == .open, let url = urls.first, url.startAccessingSecurityScopedResource() else { return }
defer {
DispatchQueue.main.async {
url.stopAccessingSecurityScopedResource()
}
}

do {
let document = try Data(contentsOf: url.absoluteURL)
parent.file = document
parent.fileName = url.lastPathComponent
print("File Selected: " + url.path)
}
catch {
print("Error selecting file: " + error.localizedDescription)
}

}

And then my Storage upload function is:

func UploadFile(doc: DocumentReference, completion:@escaping((Bool?, String?) -> () )) {
do {
let StorageReference = Storage.storage().reference().child(self.User + "/" + doc.documentID + "/" + fileName!)
StorageReference.putData(file!, metadata: nil) { (metadata, error) in
if let error = error {
self.alertMessage = error.localizedDescription
self.showingAlert = true
completion(false, nil)
}
else {
StorageReference.downloadURL { (url, error) in
if let error = error {
self.alertMessage = error.localizedDescription
self.showingAlert = true
completion(false, nil)
}
else {
ShortenUrl(from: url!.absoluteString) { result in
if (result != "") {
completion(true, result)
}
else {
completion(false, nil)
}
}
}
}
}
}
}
catch {
self.alertMessage = "Error uploading file: " + error.localizedDescription
self.showingAlert = true
completion(false, nil)
}
}


Related Topics



Leave a reply



Submit