Search code examples
iosswiftnsfilemanager

How to update an image's file directory path in Swift 3.0?


Currently I am storing the file path location of an image in the Documents directory by creating the directory path and writing the image to that directory like so:

func createDirectory() -> String
{
    let fileManager: FileManager = FileManager.default

    let dirPaths: [URL] = fileManager.urls(for: .documentDirectory, in: .userDomainMask)

    let docsDir: URL = dirPaths[0]

    let appDirPath = docsDir.appendingPathComponent("MyApp").path

    do
    {
        try fileManager.createDirectory(atPath: appDirPath,
                                        withIntermediateDirectories: true, attributes: nil)
    }
    catch let error as NSError
    {
        print("Error: \(error.localizedDescription)")
    }

    return appDirPath
}

func getPath() -> String
{
    let paths: [String] = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)

    let documentsDirectory: String = paths[0].appending("/MyApp")

    return documentsDirectory
}

func saveToDocuments()
{
    let fileManager: FileManager = FileManager.default

    let imageData: Data = UIImageJPEGRepresentation(globalImage, 1.0)!

    let dateTime: Date = Date()

    let formatter: DateFormatter = DateFormatter();

    formatter.dateFormat = "yyyy-MM-dd HH:mm:ss";
    formatter.locale =  NSLocale(localeIdentifier: "en_US_POSIX") as Locale!

    globalTimeStamp = formatter.string(from: dateTime);

    globalTimeStamp = globalTimeStamp(of: " ", with: "_")

    globalTimeStamp = globalTimeStamp + ".jpg"

    let documentsPath: URL =  try! fileManager.url(for: .documentDirectory, in: .userDomainMask,
                                                   appropriateFor: nil, create: false)

    let imagePath: URL = documentsPath.appendingPathComponent("MyApp/" + globalTimeStamp)

    let path = imagePath.path

    let success = fileManager.createFile(atPath: path as String, contents: imageData, attributes: nil)
}

The timeStamp represents the image name, which gets appended to the path of my App's directory, and written to file as seen with createFile.

My question is, if I wanted to update the globalTimeStamp somewhere else in my app, how can I update the file path to point to that SAME image instead of having to re-create another file path that points to that SAME image?

Thanks!


Solution

  • I don't quiet understand why you want to save the same file again. It is already saved. If you have changed the image in the meantime, I suggest you delete the old one and save the new one. Re-saving the same image because of some time being elapsed seems unnecessary for me. Instead, I'd rename the image by moving it to the new filepath.

    This is how I save and delete images in one of my apps under unique filenames which I then can pass around my app. I know I'm not implementing proper error handling yet but that code is from an unfinished app:

    func saveImageFile(_ image: UIImage) -> String {
        let imageName = FileManager.uniqueImageName()
        try! UIImageJPEGRepresentation(image, 1.0)?.write(to: imageName.imageUrl)
        return imageName
    }
    
    func deleteFile(named fileName: String?) {
        guard let imagePath = fileName?.imageUrl.relativePath else { return }
        guard FileManager.default.fileExists(atPath: imagePath) else { return }
        try! FileManager.default.removeItem(atPath: imagePath)
    }
    
    extension FileManager {
    
        private var imageDirectory: URL {
            let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
            let documentsDirectory = paths.first!
            return documentsDirectory
        }
    
        static func uniqueImageName() -> String {
            //Try until we get a unique filename
            while(true){
                //Generate a UUID
                let uuid = UUID().uuidString
    
                //Create the path for the file we want to use
                let filePath = uuid.imageUrl.relativePath
    
                //Check if the file already exists
                if !FileManager.default.fileExists(atPath: filePath){
                    return uuid
                }
            }
        }
    
        static func urlFor(imageNamed imageName: String) -> URL {
            return FileManager.default.imageDirectory.appendingPathComponent(imageName).appendingPathExtension("jpeg")
        }
    }
    
    extension String {
        var imageUrl: URL {
            return FileManager.urlFor(imageNamed: self)
        }
    }