IOS - How to selectively delete files older than a month in the Document Directory

I upload images to my application, which after a few weeks the user will not like it. I load them into the application, so they do not need to be downloaded every run. The problem is that I do not want the Documents folder to become larger than with time. So I thought that I could "clear" a file older than a month.

The problem is that there will be several files that will be older than a month, but I DO NOT want to delete them. They will be static named files, so they will be easy to identify, and there will only be 3 or 4. Although there may be several dozen old files that I want to delete. So here is an example:

picture.jpg <--Older than a month DELETE picture2.jpg <--NOT older than a month Do Not Delete picture3.jpg <--Older than a month DELETE picture4.jpg <--Older than a month DELETE keepAtAllTimes.jpg <--Do not delete no matter how old keepAtAllTimes2.jpg <--Do not delete no matter how old keepAtAllTimes3.jpg <--Do not delete no matter how old 

How can I selectively delete these files?

Thanks in advance!

+6
source share
6 answers

Code to delete files older than two days. I originally answered here . I tested it and it worked in my project.

PS Be careful before deleting all files in the Document directory, because you can lose the database file (if you use .. !!), which can cause problems for your application. That is why I kept if the condition is there. :-))

 // Code to delete images older than two days. #define kDOCSFOLDER [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"] NSFileManager* fileManager = [[[NSFileManager alloc] init] autorelease]; NSDirectoryEnumerator* en = [fileManager enumeratorAtPath:kDOCSFOLDER]; NSString* file; while (file = [en nextObject]) { NSLog(@"File To Delete : %@",file); NSError *error= nil; NSString *filepath=[NSString stringWithFormat:[kDOCSFOLDER stringByAppendingString:@"/%@"],file]; NSDate *creationDate =[[fileManager attributesOfItemAtPath:filepath error:nil] fileCreationDate]; NSDate *d =[[NSDate date] dateByAddingTimeInterval:-1*24*60*60]; NSDateFormatter *df=[[NSDateFormatter alloc]init];// = [NSDateFormatter initWithDateFormat:@"yyyy-MM-dd"]; [df setDateFormat:@"EEEE d"]; NSString *createdDate = [df stringFromDate:creationDate]; NSString *twoDaysOld = [df stringFromDate:d]; NSLog(@"create Date----->%@, two days before date ----> %@", createdDate, twoDaysOld); // if ([[dictAtt valueForKey:NSFileCreationDate] compare:d] == NSOrderedAscending) if ([creationDate compare:d] == NSOrderedAscending) { if([file isEqualToString:@"RDRProject.sqlite"]) { NSLog(@"Imp Do not delete"); } else { [[NSFileManager defaultManager] removeItemAtPath:[kDOCSFOLDER stringByAppendingPathComponent:file] error:&error]; } } } 
+12
source

You can get the file creation date, look at the SOA Message , and then just compare the dates. and create two different arrays for the files you need to delete and not delete.

+4
source

My two cents are worth it. Change meets the requirements.

 func cleanUp() { let maximumDays = 10.0 let minimumDate = Date().addingTimeInterval(-maximumDays*24*60*60) func meetsRequirement(date: Date) -> Bool { return date < minimumDate } func meetsRequirement(name: String) -> Bool { return name.hasPrefix(applicationName) && name.hasSuffix("log") } do { let manager = FileManager.default let documentDirUrl = try manager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) if manager.changeCurrentDirectoryPath(documentDirUrl.path) { for file in try manager.contentsOfDirectory(atPath: ".") { let creationDate = try manager.attributesOfItem(atPath: file)[FileAttributeKey.creationDate] as! Date if meetsRequirement(name: file) && meetsRequirement(date: creationDate) { try manager.removeItem(atPath: file) } } } } catch { print("Cannot cleanup the old files: \(error)") } } 
+1
source

To find the file creation date, you can refer to the very useful StackOverflow post:

iOS: how do you find the file creation date?

Refer to this post, it may help you to remove them. You can simply get a general idea of ​​what needs to be done to remove this data from the Document Directory:

How to delete files from iPhone document catalog older than 2 days

Hope this helps you.

0
source

Here is a function that does not use string comparison for dates and pre-sets the modification time in the enumerator:

 + (NSArray<NSURL *> *)deleteFilesOlderThan:(NSDate *)earliestDateAllowed inDirectory:(NSURL *)directory { NSFileManager *fileManager = [NSFileManager defaultManager]; NSDirectoryEnumerator<NSURL *> *enumerator = [fileManager enumeratorAtURL:directory includingPropertiesForKeys:@[ NSURLContentModificationDateKey ] options:0 errorHandler:^BOOL(NSURL *_Nonnull url, NSError *_Nonnull error) { NSLog(@"Failed while enumerating directory '%@' for files to " @"delete: %@ (failed on file '%@')", directory.path, error.localizedDescription, url.path); return YES; }]; NSURL *file; NSError *error; NSMutableArray<NSURL *> *filesDeleted = [NSMutableArray new]; while (file = [enumerator nextObject]) { NSDate *mtime; if (![file getResourceValue:&mtime forKey:NSURLContentModificationDateKey error:&error]) { NSLog(@"Couldn't fetch mtime for file '%@': %@", file.path, error); continue; } if ([earliestDateAllowed earlierDate:mtime] == earliestDateAllowed) { continue; } if (![fileManager removeItemAtURL:file error:&error]) { NSLog(@"Couldn't delete file '%@': %@", file.path, error.localizedDescription); continue; } [filesDeleted addObject:file]; } return filesDeleted; } 

If you do not need files that have been deleted, you can force it to return BOOL to indicate if there were any errors or just void if you just want to try with maximum effort.

To selectively save some files, add the regex argument to the function that should match the saved files, and add a check for this in the while loop (seems to be the best fit for your use), or if there is a discrete number of files with different patterns, you can accept NSSet with file names to save and verify inclusion in the set before proceeding with deletion.

We also just mention it here, as it may be relevant for some: the iOS and OSX file system does not save mtime with more accuracy than a second, so keep an eye on this if you need a millisecond of accuracy or similar.

Relevant test case if you want:

 @interface MCLDirectoryUtilsTest : XCTestCase @property NSURL *directory; @end @implementation MCLDirectoryUtilsTest - (void)setUp { NSURL *tempdir = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES]; self.directory = [tempdir URLByAppendingPathComponent:[NSUUID UUID].UUIDString isDirectory:YES]; NSFileManager *fileManager = [NSFileManager defaultManager]; [fileManager createDirectoryAtURL:self.directory withIntermediateDirectories:YES attributes:nil error:nil]; } - (void)tearDown { NSFileManager *fileManager = [NSFileManager defaultManager]; [fileManager removeItemAtURL:self.directory error:nil]; } - (void)testDeleteFilesOlderThan { NSFileManager *fileManager = [NSFileManager defaultManager]; // Create one old and one new file [fileManager createFileAtPath:[self.directory URLByAppendingPathComponent:@"oldfile"].path contents:[NSData new] attributes:@{ NSFileModificationDate : [[NSDate new] dateByAddingTimeInterval:-120], }]; [fileManager createFileAtPath:[self.directory URLByAppendingPathComponent:@"newfile"].path contents:[NSData new] attributes:nil]; NSArray<NSURL *> *filesDeleted = [MCLUtils deleteFilesOlderThan:[[NSDate new] dateByAddingTimeInterval:-60] inDirectory:self.directory]; XCTAssertEqual(filesDeleted.count, 1); XCTAssertEqualObjects(filesDeleted[0].lastPathComponent, @"oldfile"); NSArray<NSString *> *contentsInDirectory = [fileManager contentsOfDirectoryAtPath:self.directory.path error:nil]; XCTAssertEqual(contentsInDirectory.count, 1); XCTAssertEqualObjects(contentsInDirectory[0], @"newfile"); } 
0
source

In Swift 3 and 4, to delete a specific file in DocumentDirectory

 do{ try FileManager.default.removeItem(atPath: theFile) } catch let theError as Error{ print("file not found \(theError)") } 
0
source

Source: https://habr.com/ru/post/913061/


All Articles