Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FileManager says file doesn't exist when it does

I have a use case that requires a UIImage to be saved to the documents directory - then the UIImage needs to be converted into a PDF and saved to the documents directory.

CODE TO CONVERT TO PDF

var filePath = NSString(string: self.selectedMedia!.imagePath!)

if FileManager().fileExists(atPath: filePath as String) {

       filePath = filePath.deletingPathExtension as NSString
       filePath = NSString(string: filePath.appendingPathExtension("PDF")!)

       if let image = UIImage(data: self.selectedMedia?.image! as! Data) {

           let rect:CGRect = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)

           UIGraphicsBeginPDFContextToFile(filePath as String, rect, nil);
           UIGraphicsBeginPDFPageWithInfo(rect, nil);
           UIGraphicsGetCurrentContext();
           image.draw(in: rect)
           UIGraphicsEndPDFContext();

           self.selectedMedia?.imagePath = filePath as String

           CoreData.save()
       }

       self.showPDFEditor()
   }
else {
   print("Missing File At Path \(filePath)")
} 

ISSUE

FileManager says that a file does not exist when it does. The first time this is executed, before we create the PDF, FileManager can detect that image PDF does indeed exist. But After we create the PDF from the image - even though the image PNG is still in the documents directory untouched (see image below of app container for proof), FileManager says the PNG does not exist?

enter image description here

QUESTION

Why does FileManager ignore the obvious truth and keep my application from functioning?

like image 829
Brandon A Avatar asked Oct 19 '16 18:10

Brandon A


1 Answers

Never store the complete file path

My PDF and Images were residing under the Documents directory within the iOS file system. iOS will change the root path to the documents directory every time that you run the application. So saving an imagePath as I was above would work just fine, until I restarted the app. That is because I was storing the entire path to my selectedMedia object.

This now - file:///var/mobile/Containers/Data/Application/7A31EDFD-8644-45A5-8381-FE189E27D6E5/Documents/

May be this later - file:///var/mobile/Containers/Data/Application/URID09RE-5711-TI70-1252-OP4G5JH3WDST/Documents/

See how the Application/someLongNumber/ is different. This is why when you check if a file is in your documents directory and in fact is there, but the root path has changed.


What should you do?

Instead of storing the entire file path just store the subpath from the documents directory. So what I did was created a subfolder within the documents directory called Media that I save the file to and the path I store to my imagePath on my objects would be Media/theFileName.PNG.

So what you need to do is generate the path to the /Documents directory at run time. I can not stress this part enough. This will guarantee you are accessing the actual documents directory each time. Check out this SO answer for tips on how to generate the path to documents directory.

After you have the path to the run time documents directory just add your stored path to the end of that and it should look something like this:

file:///var/mobile/Containers/Data/Application/URID09RE-5711-TI70-1252-OP4G5JH3WDST/Documents/Media/theFileName.PNG

like image 78
Brandon A Avatar answered Sep 22 '22 09:09

Brandon A