iosswiftnsfilemanagernsdocumentdirectory

Save file in document directory in swift 3?


I am saving files in a document directory in swift 3 with this code:

fileManager = FileManager.default
// let documentDirectory = fileManager?.urls(for: .documentDirectory, in: .userDomainMask).first as String
var path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
path = path + name

let image = #imageLiteral(resourceName: "Notifications")
let imageData = UIImageJPEGRepresentation(image, 0.5)
let bool = fileManager?.createFile(atPath: path, contents: imageData, attributes: nil)

print("bool is \(bool)")
return true

But as you can see, I am not using filemanager to get document directory path as filemanager gives only URL not string.

Questions:


Solution

  • Please think the other way round.

    URL is the recommended way to handle file paths because it contains all convenience methods for appending and deleting path components and extensions – rather than String which Apple has removed those methods from.

    You are discouraged from concatenating paths like path = path + name. It's error-prone because you are responsible for all slash path separators.

    Further you don't need to create a file with FileManager. Data has a method to write data to disk.

    let fileManager = FileManager.default
    do {
        let documentDirectory = try fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor:nil, create:false)
        let fileURL = documentDirectory.appendingPathComponent(name)
        let image = #imageLiteral(resourceName: "Notifications")
        if let imageData = image.jpegData(compressionQuality: 0.5) {
            try imageData.write(to: fileURL)
            return true
        }
    } catch {
        print(error)
    }
    return false
    

    Alternatively make the function throw and hand over the error to the caller

    func saveFile(with name: String) throws {
        let fileManager = FileManager.default
        let documentDirectory = try fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
        let fileURL = documentDirectory.appendingPathComponent(name)
        let image = #imageLiteral(resourceName: "Notifications")
        guard let imageData = image.jpegData(compressionQuality: 0.5) else { throw URLError(.cannotDecodeContentData) }
        try imageData.write(to: fileURL)
    }
    

    In iOS 16+, macOS 13+ there is a more convenient way to get the URL to the documents directory without FileManager

    let documentDirectory = URL.documentsDirectory