1

I have the following swift function that I hoped would save incoming bytes to a JPEG file on iOS. Unfortunately an exception is thrown by the call to data.write and I get the error message

The folder “studioframe0.jpg” doesn’t exist. writing to file:/var/mobile/Containers/Data/Application/2A504F84-E8B7-42F8-B8C3-3D0A53C1E11A/Documents/studioframe0.jpg -- file:///

Why does iOS think it is a directory path to a directory which does not exist as opposed to a file that I am asking it to write?

func saveToFile(data: Data){
    if savedImageCount < 10 {
        guard let documentDirectoryPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
            return
        }
        let imgPath = URL(fileURLWithPath: documentDirectoryPath.appendingPathComponent("studioframe\(savedImageCount).jpg").absoluteString)
        savedImageCount += 1
        do {
            try data.write(to: imgPath, options: .atomic)
            print("Saved \(imgPath) to disk")
        } catch let error {
            print("\(error.localizedDescription) writing to \(imgPath)")
        }
    }
}
dumbledad
  • 16,305
  • 23
  • 120
  • 273
  • this should be reopened, the uiimage issue is something else.. here the issue is that the intermediary directory hasn't yet been created. this can be created through the filemanager, then it will no longer confuse one's file for a folder. the accepted answer is a good workaround, but doesn't address the core issue of missing directories. – Logan Feb 07 '20 at 19:22

1 Answers1

2

URL(fileURLWithPath together with absoluteString is wrong.

You would have to write (note the different URL initializer):

let imgPath = URL(string: documentDirectoryPath.appendingPathComponent("studioframe\(savedImageCount).jpg").absoluteString)

but this (URLStringURL) is very cumbersome, there is a much simpler solution, please consider the difference between (string) path and URL

let documentDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! // the Documents directory is guaranteed to exist.
let imgURL = documentDirectoryURL.appendingPathComponent("studioframe\(savedImageCount).jpg")
...
   try data.write(to: imgURL, options: .atomic)
vadian
  • 274,689
  • 30
  • 353
  • 361