'File' couldn’t be moved because you don’t have permission to access 'Documents'

Hi there,

I am attempting to move a file to the documents folder programmatically within my iOS app. See below for a code snippet, nothing crazy just simple FileManager interactions.

func moveZip(sourceUrl: URL) -> URL? {

        let destinationUrl: URL = getDocumentsDirectory().appendingPathComponent(sourceUrl.lastPathComponent)

        do {

            if FileManager.default.fileExists(atPath: destinationUrl.path) {

                try FileManager.default.removeItem(atPath: destinationUrl.path)

            }

            try FileManager.default.moveItem(atPath: sourceUrl.path, toPath: destinationUrl.path)

                return destinationUrl

        } catch {

            print(error.localizedDescription)

            return nil

        }

    }

sourceUrl = file:///private/var/mobile/Containers/Shared/AppGroup/XXXXXXXXXXXXXXXXXXXXX/File%20Provider%20Storage/Work/file.zip

destinationUrl = file:///var/mobile/Containers/Data/Application/XXXXXXXXXXXXXXXXXXXXX/Documents/file.zip

Once I hit the line try FileManager.default.moveItem call I fail out with the following error: “file.zip” couldn’t be moved because you don’t have permission to access “Documents”.

I believe I'm accessing everything correctly and have tried to dig into any possible info.plst access privileges but I haven't found anything yet.

Running Xcode Version 13.0 beta and targeting an iPhone 11 Pro Max running iOS v14.7.

Any help is appreciated!

Thanks!

Answered by Claude31 in 686825022

Is it the documents folder of the app ?

Have a look at this: https://developer.apple.com/forums/thread/76609

Accepted Answer

Is it the documents folder of the app ?

Have a look at this: https://developer.apple.com/forums/thread/76609

I cannot seem to edit the original post but based on @OOPer's suggestion to retry the startAccessingSecurityScopedResource method I was able to get this working. Adding my code here as an example for anyone that may find this useful. Thank you @OOPer and @Claude31.

.fileImporter(isPresented: $isImporting, allowedContentTypes: [.zip], allowsMultipleSelection: false
    ) { result in
        do {
            guard let selectedFile: URL = try result.get().first else { return }
            if selectedFile.startAccessingSecurityScopedResource() {
                guard let dest = moveZip(sourceUrl: selectedFile) else { print("Error")
                    return
                }
                self.dfuFile = dest
                selectedFile.stopAccessingSecurityScopedResource()
            }
            self.dfuFirmware = DFUFirmware(urlToZipFile: self.dfuFile, type: DFUFirmwareType.application)
            self.dfuActive = true
         } catch {
             // Handle the Failure
             print("Unable to read file")
             print(error.localizedDescription)
         }
    }

Just to add. I also had trouble moving a file with moveItem from <private/var/.../tmp/...> (image picker automatically saved the images here for me). But I just changed the function to copyItem, and then it worked. Hope it helps someone.

This was really a quite useful thread, because security sandbox issues are difficult to manage using just Apple official documentation. Thanks to @Crudough Crudough that pose the question (and the final correct code) and to @OOPer and @Claude31 for the guidelines.

'File' couldn’t be moved because you don’t have permission to access 'Documents'
 
 
Q