55

I downloaded some PDF files in my app and want to delete these on closing the application.

For some reason it does not work:

Creating the file:

let reference = "test.pdf"    
let RequestURL = "http://xx/_PROJEKTE/xx\(self.reference)"
let ChartURL = NSURL(string: RequestURL)

//download file
let documentsUrl =  NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first! as NSURL
let destinationUrl = documentsUrl.URLByAppendingPathComponent(ChartURL!.lastPathComponent!)
if NSFileManager().fileExistsAtPath(destinationUrl.path!) {
    print("The file already exists at path")
} else {
    //  if the file doesn't exist
    //  just download the data from your url
    if let ChartDataFromUrl = NSData(contentsOfURL: ChartURL!){
        // after downloading your data you need to save it to your destination url
        if ChartDataFromUrl.writeToURL(destinationUrl, atomically: true) {
            print("file saved")
            print(destinationUrl)
        } else {
            print("error saving file")
        }
    }
}

Then I want to call the test() function to remove the items, like this:

func test(){

    let fileManager = NSFileManager.defaultManager()
    let documentsUrl =  NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first! as NSURL

    do {
        let filePaths = try fileManager.contentsOfDirectoryAtPath("\(documentsUrl)")
        for filePath in filePaths {
            try fileManager.removeItemAtPath(NSTemporaryDirectory() + filePath)
        }
    } catch {
        print("Could not clear temp folder: \(error)")
    }
}
Lucas Huang
  • 3,998
  • 3
  • 20
  • 29
Fabian Boulegue
  • 6,476
  • 14
  • 47
  • 72
  • 2
    I suspect you want to consider using `.CachesDirectory` rather than `.DocumentDirectory` for saving and deleting these files. – TwoStraws Dec 19 '15 at 10:27
  • i did try to save my file there but it did not work – Fabian Boulegue Dec 19 '15 at 10:30
  • 2
    You should definitely read through [app backup best practices](https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/PerformanceTips/PerformanceTips.html#//apple_ref/doc/uid/TP40007072-CH7-SW17) and [QA1719](https://developer.apple.com/library/ios/qa/qa1719/_index.html) then. – TwoStraws Dec 19 '15 at 10:32
  • @TwoStraws Good point, a lot of answers on SO just use the documents directory but they shouldn't... – J. Doe Oct 22 '17 at 13:09

5 Answers5

65

This code works for me. I removed all the images that were cached.

private func test(){

    let fileManager = NSFileManager.defaultManager()
    let documentsUrl =  NSFileManager.defaultManager().URLsForDirectory(.CachesDirectory, inDomains: .UserDomainMask).first! as NSURL
    let documentsPath = documentsUrl.path

    do {
        if let documentPath = documentsPath
        {
            let fileNames = try fileManager.contentsOfDirectoryAtPath("\(documentPath)")
            print("all files in cache: \(fileNames)")
            for fileName in fileNames {

                if (fileName.hasSuffix(".png"))
                {
                    let filePathName = "\(documentPath)/\(fileName)"
                    try fileManager.removeItemAtPath(filePathName)
                }
            }

            let files = try fileManager.contentsOfDirectoryAtPath("\(documentPath)")
            print("all files in cache after deleting images: \(files)")
        }

    } catch {
        print("Could not clear temp folder: \(error)")
    }
}

**** Update swift 3 ****

        let fileManager = FileManager.default
        let documentsUrl =  FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first! as NSURL
        let documentsPath = documentsUrl.path

        do {
            if let documentPath = documentsPath
            {
                let fileNames = try fileManager.contentsOfDirectory(atPath: "\(documentPath)")
                print("all files in cache: \(fileNames)")
                for fileName in fileNames {

                    if (fileName.hasSuffix(".png"))
                    {
                        let filePathName = "\(documentPath)/\(fileName)"
                        try fileManager.removeItem(atPath: filePathName)
                    }
                }

                let files = try fileManager.contentsOfDirectory(atPath: "\(documentPath)")
                print("all files in cache after deleting images: \(files)")
            }

        } catch {
            print("Could not clear temp folder: \(error)")
        }
Duck
  • 34,902
  • 47
  • 248
  • 470
Saleh Masum
  • 2,137
  • 1
  • 16
  • 16
28

I believe your problem is on this line:

let filePaths = try fileManager.contentsOfDirectoryAtPath("\(documentsUrl)")

You're using contentsOfDirectoryAtPath() with something that is an NSURL. You choose either path strings or URLs, not try to mix them both. To pre-empty your possible next question, URLs are preferred. Try using contentsOfDirectoryAtURL() and removeItemAtURL().

Another curious thing you should look at once you resolve the above: why are you using NSTemporaryDirectory() for the file path when you try to delete? You're reading the document directory and should use that.

TwoStraws
  • 12,862
  • 3
  • 57
  • 71
  • is there a way to delete the "complete CachesDirectory()"? – Fabian Boulegue Dec 19 '15 at 10:33
  • Documents and Library/Caches shouldn't be deleted. Add and remove files if you want, but don't delete them. Note: Llibrary/Caches should be cleared for you by iOS as needed. – TwoStraws Dec 19 '15 at 10:34
  • so did i understand it right -> don't delete the stored files in CachesDirectory(), iOS ll "delete" them by it self? – Fabian Boulegue Dec 19 '15 at 10:37
  • No, I said "add and remove them if you want." You *can* delete files (not the directory itself!) in the Library/Caches directory, but you don't *need* to if you don't want to. iOS will always clear caches if the user's device is running low on space. It's down to you and how you want your application to behave :) – TwoStraws Dec 19 '15 at 10:38
  • Ah ok, thanks, then i need to look for a way to delete "all PDFs" in there :-)! – Fabian Boulegue Dec 19 '15 at 10:39
  • @TwoStraws can we delete file which is on `Bundle` – Jack Jun 18 '18 at 04:53
6

Swift 5:

Check out the FileManager.removeItem() method

// start with a file path, for example:
let fileUrl = FileManager.default.urls(
    for: .documentDirectory,
    in: .userDomainMask
).deletingPathExtension()
    .appendingPathComponent(
        "someDir/customFile.txt",
        isDirectory: false
    )

// check if file exists
// fileUrl.path converts file path object to String by stripping out `file://`
if FileManager.default.fileExists(atPath: fileUrl.path) {
    // delete file
    do {
        try FileManager.default.removeItem(atPath: fileUrl.path)
    } catch {
        print("Could not delete file, probably read-only filesystem")
    }
} 
Adonis Gaitatzis
  • 3,189
  • 26
  • 24
0

It's usually just one line of code.

FileManager.default.removeItem(at: untoUrl)

Just eliminate the whole directory, and make it again. It's much more reliable, simple, understandable.

You see this idiom always ..

let untoUrl = FileManager().temporaryDirectory.appendingPathComponent("temp")

do {
    try FileManager.default.removeItem(at: untoUrl)
    try FileManager().createDirectory(at: untoUrl, withIntermediateDirectories: true)

     .. create your files or whatever ..
}
catch { print(error) }

That's it

miken32
  • 42,008
  • 16
  • 111
  • 154
Fattie
  • 27,874
  • 70
  • 431
  • 719
0

I am using the following methods to save, get and remove video...

//MARK: video add, remove and get methods 
func saveVideoToDisk(videoURL : URL){
    // Save the video to disk.
    let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    let videoPath = documentsDirectory.appendingPathComponent("tempVideo.mov")
    // Delete the video from disk if already exist
    try? FileManager.default.removeItem(at: videoPath)
    // Save the video to disk.
    try? FileManager.default.copyItem(at: videoURL, to: videoPath)
}

func getSavedVideoURL() -> URL{
    // Save the video to disk.
    let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    let videoPath = documentsDirectory.appendingPathComponent("tempVideo.mov")
    let videoURL = URL(fileURLWithPath: videoPath.path)
    
    return videoURL
}

func removeSavedVideo(){
    // Save the video to disk.
    let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    let videoPath = documentsDirectory.appendingPathComponent("tempVideo.mov")
    
    // Delete the video from disk
    try? FileManager.default.removeItem(at: videoPath)
}

func isSavedVideoExist() -> Bool{
    // Save the video to disk.
    let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    let videoPath = documentsDirectory.appendingPathComponent("tempVideo.mov")

    // Check if the file exists.
    let fileExists = FileManager.default.fileExists(atPath: videoPath.path)
    
    return fileExists
}
Wahab Khan Jadon
  • 875
  • 13
  • 21