How to remove tmp directory files of an ios app?
Asked Answered
G

9

52

I'm working on an app that uses the iPhone camera and after making several tests I've realised that it is storing all the captured videos on the tmp directory of the app. The captures don`t disappear even if the phone is restarted.

Is there any way to remove all these captures or is there any way to easily clean all cache and temp files?

Genteelism answered 8/2, 2012 at 15:37 Comment(0)
S
51

Yes. This method works well:

+ (void)clearTmpDirectory
{
    NSArray* tmpDirectory = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:NSTemporaryDirectory() error:NULL];
    for (NSString *file in tmpDirectory) {
        [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@%@", NSTemporaryDirectory(), file] error:NULL];
    }
}
Seaquake answered 14/6, 2013 at 1:4 Comment(2)
How about [[NSFileManager defaultManager] removeItemAtPath:NSTemporaryDirectory() error:NULL];?Meldameldoh
@Meldameldoh The directory should not be deleted. Some operations get failed.Gagnon
N
37

Swift 3 version as extension:

extension FileManager {
    func clearTmpDirectory() {
        do {
            let tmpDirectory = try contentsOfDirectory(atPath: NSTemporaryDirectory())
            try tmpDirectory.forEach {[unowned self] file in
                let path = String.init(format: "%@%@", NSTemporaryDirectory(), file)
                try self.removeItem(atPath: path)
            }
        } catch {
            print(error)
        }
    }
}

Example of usage:

FileManager.default.clearTmpDirectory()

Thanks to Max Maier, Swift 2 version:

func clearTmpDirectory() {
    do {
        let tmpDirectory = try NSFileManager.defaultManager().contentsOfDirectoryAtPath(NSTemporaryDirectory())
        try tmpDirectory.forEach { file in
            let path = String.init(format: "%@%@", NSTemporaryDirectory(), file)
            try NSFileManager.defaultManager().removeItemAtPath(path)
        }
    } catch {
        print(error)
    }
}
Neoteric answered 5/5, 2016 at 6:26 Comment(0)
F
28

Swift 4

One of the possible implementations

extension FileManager {
    func clearTmpDirectory() {
        do {
            let tmpDirURL = FileManager.default.temporaryDirectory
            let tmpDirectory = try contentsOfDirectory(atPath: tmpDirURL.path)
            try tmpDirectory.forEach { file in
                let fileUrl = tmpDirURL.appendingPathComponent(file)
                try removeItem(atPath: fileUrl.path)
            }
        } catch {
           //catch the error somehow
        }
    }
}
Faeroese answered 28/12, 2017 at 13:24 Comment(4)
Should be try fileManager.contentsOfDirectory(atPath: tmpDirURL.path)Anemophilous
it is an extension, so no need for that.Leavelle
I would add a secondary do-catch for each removeItem element. If one element gets stuck, the rest will never delete.Gaspard
Why are you referencing the default file manager when this is an extension of FileManager?Cloris
E
5

Thanks to Max Maier and Roman Barzyczak. Updated to Swift 3, using URLs instead of strings.

Swift 3

func clearTmpDir(){

        var removed: Int = 0
        do {
            let tmpDirURL = URL(string: NSTemporaryDirectory())!
            let tmpFiles = try FileManager.default.contentsOfDirectory(at: tmpDirURL, includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
            print("\(tmpFiles.count) temporary files found")
            for url in tmpFiles {
                removed += 1
                try FileManager.default.removeItem(at: url)
            }
            print("\(removed) temporary files removed")
        } catch {
            print(error)
            print("\(removed) temporary files removed")
        }
}
Espino answered 9/2, 2017 at 16:44 Comment(0)
U
4

Try this code to remove NSTemporaryDirectory files

-(void)deleteTempData
{
    NSString *tmpDirectory = NSTemporaryDirectory();
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *cacheFiles = [fileManager contentsOfDirectoryAtPath:tmpDirectory error:&error];
    for (NSString *file in cacheFiles)
    {
        error = nil;
        [fileManager removeItemAtPath:[tmpDirectory stringByAppendingPathComponent:file] error:&error];
    }
}

and to check data remove or not write code in didFinishLaunchingWithOptions

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    [self.window makeKeyAndVisible];

    NSString *tmpDirectory = NSTemporaryDirectory();
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *cacheFiles = [fileManager contentsOfDirectoryAtPath:tmpDirectory error:&error];
    NSLog(@"TempFile Count ::%lu",(unsigned long)cacheFiles.count);

    return YES;
}
Unreliable answered 27/12, 2014 at 9:59 Comment(0)
F
3

I know i'm late to the party but i'd like to drop my implementation which works straight on URLs, too:

let fileManager = FileManager.default
let temporaryDirectory = fileManager.temporaryDirectory
try? fileManager
    .contentsOfDirectory(at: temporaryDirectory, includingPropertiesForKeys: nil, options: .skipsSubdirectoryDescendants)
    .forEach { file in
        try? fileManager.removeItem(atPath: file.path)
    }
Forebear answered 1/9, 2022 at 12:47 Comment(0)
U
2

This works on a jailbroken iPad, but I think this should work on a non-jailbroken device also.

-(void) clearCache
{
    for(int i=0; i< 100;i++)
    {
        NSLog(@"warning CLEAR CACHE--------");
    }
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError * error;
    NSArray * cacheFiles = [fileManager contentsOfDirectoryAtPath:NSTemporaryDirectory() error:&error];

    for(NSString * file in cacheFiles)
    {
        error=nil;
        NSString * filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:file ];
        NSLog(@"filePath to remove = %@",filePath);

        BOOL removed =[fileManager removeItemAtPath:filePath error:&error];
        if(removed ==NO)
        {
            NSLog(@"removed ==NO");
        }
        if(error)
        {
            NSLog(@"%@", [error description]);
        }
    }
}
Undertow answered 16/6, 2012 at 12:24 Comment(1)
To let you know I tried this on an non-jailbroken iphone ios6, works great. Thanks.Jurassic
C
0
//
//  FileManager+removeContentsOfTemporaryDirectory.swift
//
//  Created by _ _ on _._.202_.
//  Copyright © 202_ _ _. All rights reserved.
//

import Foundation

public extension FileManager {

    /// Perform this method on a background thread.
    /// Returns `true` if :
    ///     * all temporary folder files have been deleted.
    ///     * the temporary folder is empty.
    /// Returns `false` if :
    ///     * some temporary folder files have not been deleted.
    /// Error handling:
    ///     * Throws `contentsOfDirectory` directory access error.
    ///     * Ignores single file `removeItem` errors.
    ///
    @discardableResult
    func removeContentsOfTemporaryDirectory() throws -> Bool  {
        
        if Thread.isMainThread {
            let mainThreadWarningMessage = "\(#file) - \(#function) executed on main thread. Do not block the main thread."
            assertionFailure(mainThreadWarningMessage)
        }
        
        do {
            
            let tmpDirURL = FileManager.default.temporaryDirectory
            let tmpDirectoryContent = try contentsOfDirectory(atPath: tmpDirURL.path)
            
            guard tmpDirectoryContent.count != 0 else { return true }
            
            for tmpFilePath in tmpDirectoryContent {
                let trashFileURL = tmpDirURL.appendingPathComponent(tmpFilePath)
                try removeItem(atPath: trashFileURL.path)
            }
            
            let tmpDirectoryContentAfterDeletion = try contentsOfDirectory(atPath: tmpDirURL.path)
            
            return tmpDirectoryContentAfterDeletion.count == 0
            
        } catch let directoryAccessError {
            throw directoryAccessError
        }
        
    }
}
Crimmer answered 5/4, 2022 at 9:56 Comment(0)
M
0

Use this dedicated code to remove all tmp files:

let directory = FileManager.default.temporaryDirectory
try contentsOfDirectory(at: directory, includingPropertiesForKeys: []).forEach(removeItem)

You filter the contents before performing the forEach if you need

Moony answered 29/6, 2023 at 14:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.