14

I am downloading a file to a folder and I am validating that the file is indeed there in the code, but I am getting the above error. Can someone help me figure out why i dont have permissions to read this file?

let documentsURL = NSSearchPathForDirectoriesInDomains
(.DocumentDirectory, .UserDomainMask, true)[0]

let checkValidation = NSFileManager.defaultManager()

if (checkValidation.fileExistsAtPath(documentsURL))
{
    print("FILE AVAILABLE");
}
else
{
    print("FILE NOT AVAILABLE");
}

print(documentsURL)

do{
    let data = try String(contentsOfFile: documentsURL as String,
                          encoding: NSASCIIStringEncoding)
    print(data)
    
}
catch let error { print(error) }

Error Domain=NSCocoaErrorDomain Code=257 "The file “Documents” couldn’t be opened because you don’t have permission to view it." UserInfo={NSFilePath=/var/mobile/Containers/Data/Application/7FA4D6A9-2149-4053-BF08-22E94A00AE34/Documents, NSUnderlyingError=0x137807200 {Error Domain=NSPOSIXErrorDomain Code=13 "Permission denied"}}

aturan23
  • 4,798
  • 4
  • 28
  • 52
user3395936
  • 651
  • 3
  • 13
  • 26
  • I would consider printing the URL you cast to a String first, it most likely is not a good idea to use NSURL and String that way. Consider using NSURL.relativePath instead. – Antwan van Houdt Apr 01 '16 at 11:25
  • @AntwanvanHoudt sorry i am not understanding what you want me to do? How do i use NSURL.relativePath? Besides this piece of code was running for me before as String, so I doubt that it is the issue – user3395936 Apr 01 '16 at 11:32
  • "documentsDirectoryURL.relativePath!" instead of the cast. – Antwan van Houdt Apr 01 '16 at 12:14
  • @AntwanvanHoudt gives me this error : ` Value of type 'String' has no member 'relativePath'` – user3395936 Apr 01 '16 at 12:24
  • Where does documentsDirectoryPath come from, you don't define it in your snippet of code.... yet you reread the URL From NSSearchPath and end up not using it. Also the documentsURL will always result in a file available since the directory is part of your app bundle, why you cheking for that? You should be checking for the URL of your FILE not the documents folder – Antwan van Houdt Apr 01 '16 at 12:27
  • @AntwanvanHoudt apologies, you were right, i just didnt edit out the code correctly, instead of documentsDirectoryPath it should be documentsURL. To answer your second question, I must disagree because it does indeed check for a file there because when there is no file it gives me `FILE NOT AVAILABLE`, so I think this code works on my end? – user3395936 Apr 01 '16 at 12:31
  • Now isn't it pretty self-descriptive what the problem is? You don't have permission to view the file. – nhgrif Apr 01 '16 at 12:48
  • @nhgrif any idea how i can't get this permission? – user3395936 Apr 01 '16 at 12:57
  • @user3395936 did you find a solution to this problem? – Chris Jun 08 '16 at 18:36
  • Are u popping the GalleryVC after selecting the PHAsset.. because popping the VC causes the instance to die and make the URL invalid thus leading to the above error. If you push a new VC or stay in the same VC and upload then this should not happen. – Maddiee May 29 '17 at 18:00

2 Answers2

38

Try

fileURL.startAccessingSecurityScopedResource()
//...
fileURL.stopAccessingSecurityScopedResource()
Ivan Vavilov
  • 1,520
  • 1
  • 15
  • 28
  • 5
    This resolved the error for me when trying to get the data content for a file on start-up. – Adrian Schönig May 02 '19 at 14:44
  • @Ivan Vavilov I have just come across this issue, I want to be able to access any file the user chooses. When I state startAccessingSecurityScopedResource, XCode tells me it is unused. Do you know what could've happened here? It returns true but I still don't have permission to access the file. – DischordDynne Mar 16 '23 at 19:28
8

Your documentsURL is the address of the Documents FOLDER in your app. It is not a FILE that you can get the contents of:

/var/mobile/Containers/Data/Application/7FA4D6A9-2149-4053-BF08-22E94A00AE34/Documents

Matt_S
  • 315
  • 1
  • 7
  • 1
    So why is that when I run this code `if (checkValidation.fileExistsAtPath(documentsURL))` it says that the document exists at that path? – user3395936 Apr 06 '16 at 14:44
  • @user3395936 Because that API returns `true` far too often. What you want to do is `documentsURL.hasDirectoryPath`, which will tell you if that's a directory. If you want to get the child files within the directory, use `FileManager.default.contentsOfDirectory(at: documentsURL, includingPropertiesForKeys: nil, options: []))` – Ky - Jun 07 '17 at 15:32
  • .fileExistsAtPath means there is _something_ - a file, folder, bundle... you want fileExistsAtPath: isDirectory to check whether it's a directory or not. – green_knight Mar 13 '18 at 00:03