darkginger
darkginger

Reputation: 690

Remove all files from within documentDirectory in Swift

I am making an audio app, and the user can download files locally stored to the documentDirectory using FileManager.

Next, I'd like to allow the user to delete all files using a button. In the documentation, there is a method to remove items.

Here's my code:

@IBAction func deleteDirectoryButton(_ sender: Any) {

    let documentsUrl =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!

        do {
            try FileManager.default.removeItem(at: documentsUrl, includingPropertiesForKeys: nil, options: [])

        } catch let error {
            print(error)
        }
    }

Unfortunately, this won't build with an error Ambiguous reference to member 'removeItem(atPath:)'.

Is there a better approach to access the documentDirectory and remove all files from the directory in one swoop?

Upvotes: 19

Views: 20747

Answers (5)

vadian
vadian

Reputation: 285074

First of all the error occurs because the signature of the API is wrong. It's just removeItem(at:) without the other parameters.

A second issue is that you are going to delete the Documents directory itself rather than the files in the directory which you are discouraged from doing that.

You have to get the contents of the directory and add a check for example to delete only MP3 files. A better solution would be to use a subfolder.

let documentsUrl = URL.documentsDirectory

do {
    let fileURLs = try FileManager.default.contentsOfDirectory(at: documentsUrl,
                                                               includingPropertiesForKeys: nil,
                                                               options: .skipsHiddenFiles)
    for fileURL in fileURLs where fileURL.pathExtension == "mp3" {
        try FileManager.default.removeItem(at: fileURL)   
    }
} catch  { print(error) }

Side note: It is highly recommended to use always the URL related API of FileManager.

Upvotes: 49

iParesh
iParesh

Reputation: 2368

Try this

func clearAllFiles() {
    let fileManager = FileManager.default
        
    let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
        
    print("Directory: \(paths)")
        
    do {
        let fileName = try fileManager.contentsOfDirectory(atPath: paths)
            
        for file in fileName {
            // For each file in the directory, create full path and delete the file
            let filePath = URL(fileURLWithPath: paths).appendingPathComponent(file).absoluteURL
            try fileManager.removeItem(at: filePath)
        }
    } catch let error {
        print(error)
    }
}

Upvotes: 5

8HP8
8HP8

Reputation: 1908

Swift 5

Delete the whole folder:

If you'd like to delete a whole folder you can simply do this:

func deleteFolder(_ folderName: String, completion: () -> Void) {
    let fileManager = FileManager.default
    let directory = fileManager.cachesDirectory().appendingPathComponent(folderName)
    _ = try? fileManager.removeItem(at: directory)
    completion()
}

Delete certain files based on their name:

This will loop through all the files and remove all that contain the

func removeFiles(containing: String, completion: () -> Void) {
    let fileManager = FileManager.default
    let directory = fileManager.cachesDirectory()
    
    if let fileNames = try? fileManager.contentsOfDirectory(atPath: directory.path) {
        for file in fileNames {
            if file.contains(containing) {
                let filePath = URL(fileURLWithPath: directory.path).appendingPathComponent(file).absoluteURL
                _ = try? fileManager.removeItem(at: filePath)
            }
        }
    }
    completion()
}

Upvotes: 0

YanSte
YanSte

Reputation: 10839

This my extension for remove all files and caches from directory.

// MARK: - FileManager extensions

extension FileManager {
    
    /// Remove all files and caches from directory.
    public static func removeAllFilesDirectory() {
        let fileManager = FileManager()
        let mainPaths = [
            FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).map(\.path)[0],
            FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).map(\.path)[0]
        ]
        mainPaths.forEach { mainPath in
            do {
                let content = try fileManager.contentsOfDirectory(atPath: mainPath)
                content.forEach { file in
                    do {
                        try fileManager.removeItem(atPath: URL(fileURLWithPath: mainPath).appendingPathComponent(file).path)
                    } catch {
                        // Crashlytics.crashlytics().record(error: error)
                    }
                }
            } catch {
                // Crashlytics.crashlytics().record(error: error)
            }
        }
    }
}

Upvotes: 2

iOS Geek
iOS Geek

Reputation: 4855

Just use code as Follow

to save AudioFile in Document Directory as

func getDocumentsDirectory() -> URL
    {
        //Get Basic URL
        let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
        /// Enter a Directory Name in which files will be saved
        let dataPath1 = documentsDirectory.appendingPathComponent("folder_name_enter")
        let dataPath = dataPath1.appendingPathComponent("folder inside directory if required (name)")
        //Handler
        do
        {
            try FileManager.default.createDirectory(atPath: dataPath.path, withIntermediateDirectories: true, attributes: nil)
        }
        catch let error as NSError
        {
            print("Error creating directory: \(error.localizedDescription)")
        }
        return dataPath
    }

Delete

func clearAllFilesFromTempDirectory()
    {
        let fileManager = FileManager.default
        let dirPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
        let tempDirPath = dirPath.appending("/folder_name/\(inside_directoryName)")

        do {
            let folderPath = tempDirPath
            let paths = try fileManager.contentsOfDirectory(atPath: tempDirPath)
            for path in paths
            {
                try fileManager.removeItem(atPath: "\(folderPath)/\(path)")
            }
        }
        catch let error as NSError
        {
            print(error.localizedDescription)
        }
    }

Saving Method

getDocumentsDirectory().appendingPathComponent("\(audioName).wav")

Deletion Method

/// Just call
clearAllFilesFromTempDirectory

Upvotes: 4

Related Questions