I used NSFileManager to retrieve the files in a folder, and I want to sort them by modified date. How to do that ?
Thanks.
What have you tried so far?
I haven't done this, but a quick look at the docs makes me think that you should try the following:
Call -contentsOfDirectoryAtURL:includingPropertiesForKeys:options:error: and specify NSURLContentModificationDateKey as one of the keys.
You'll get back an array of NSURL objects which you can then sort using an NSArray method like -sortedArrayUsingComparator:.
Pass in a comparator block that looks up the modification date for each NSURL using -getResourceValue:forKey:error:.
Update: When I wrote the answer above, -getResourceValue:forKey:error: existed in iOS but didn't do anything. That method is now functional as of iOS 5. The following code will log an app's resource files followed by a list of corresponding modification dates:
NSFileManager *manager = [NSFileManager defaultManager];
NSArray *files = [manager contentsOfDirectoryAtURL:[[NSBundle mainBundle] resourceURL]
includingPropertiesForKeys:[NSArray arrayWithObject:NSURLContentModificationDateKey]
options:nil
error:nil];
NSMutableArray *dates = [NSMutableArray array];
for (NSURL *f in files) {
NSDate *d = nil;
if ([f getResourceValue:&d forKey:NSURLContentModificationDateKey error:nil]) {
[dates addObject:d];
}
}
NSLog(#"Files: %#", files);
NSLog(#"Dates: %#", dates);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSFileManager *manager = [NSFileManager defaultManager];
NSArray *imageFilenames = [manager contentsOfDirectoryAtPath:documentsDirectory error:nil];
NSMutableArray *originalImage = [[NSMutableArray alloc]init];
for (int i = 1; i < [imageFilenames count]; i++)
{
NSString *imageName = [NSString stringWithFormat:#"%#/%#",documentsDirectory,[imageFilenames objectAtIndex:i] ];
}
//---------sorting image by date modified
NSArray* filelist_date_sorted;
filelist_date_sorted = [imageFilenames sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2)
{
NSDictionary* first_properties = [[NSFileManager defaultManager] attributesOfItemAtPath:[NSString stringWithFormat:#"%#/%#", documentsDirectory, obj1] error:nil];
NSDate *first = [first_properties objectForKey:NSFileCreationDate];
NSDictionary *second_properties = [[NSFileManager defaultManager] attributesOfItemAtPath:[NSString stringWithFormat:#"%#/%#", documentsDirectory, obj2] error:nil];
NSDate *second = [second_properties objectForKey:NSFileCreationDate];
return [second compare:first];
}];
NSLog(#" Date sorted result is %#",filelist_date_sorted);
static static NSInteger contentsOfDirSort(NSString *left, NSString *right, void *ptr) {
(void)ptr;
struct stat finfo_l, r_finfo_r;
if(-1 == stat([left UTF8String], &finfo_l))
return NSOrderedSame;
if(-1 == stat([right UTF8String], &finfo_r))
return NSOrderedSame;
if(finfo_l.st_mtime < finfo_r.st_mtime)
return NSOrderedAscending;
if(finfo_l.st_mtime > finfo_r.st_mtime)
return NSOrderedDescending;
return NSOrderedSame;
}
Now, later on in your code.
NSMutableArray *mary = [NSMutableArray arrayWithArray:filePathsArray];
[mary sortUsingFunction:contentsOfDirSort context:nil];
// Use mary...
Quick Method:
-(void)dateModified
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSFileManager *manager = [NSFileManager defaultManager];
NSArray *fileList = [manager contentsOfDirectoryAtPath:documentsDirectory error:nil];
//--- Listing file by name sort
NSLog(#"\n File list %#",fileList);
int num;
//-- Listing file name with modified dated
for (NSString *s in fileList)
{
NSString *filestring = [documentsDirectory stringByAppendingFormat:#"/%#",s];
NSDictionary *filePathsArray1 = [[NSFileManager defaultManager] attributesOfItemAtPath:filestring error:nil];
NSString *modifiedDate = [filePathsArray1 objectForKey:NSFileModificationDate];
NSLog(#"\n Modified Day : %#", modifiedDate);
num=num+1;
}
}
In a category over NSFileManager:
static NSInteger contentsOfDirSort(NSURL *leftURL, NSURL *rightURL, void *ptr)
{
(void)ptr;
NSDate * dateLeft ;
[leftURL getResourceValue:&dateLeft
forKey:NSURLContentModificationDateKey
error:nil] ;
NSDate * dateRight ;
[rightURL getResourceValue:&dateRight
forKey:NSURLContentModificationDateKey
error:nil] ;
return [dateLeft compare:dateRight];
}
- (NSArray *)contentsOrderedByDateOfDirectoryAtPath:(NSURL *)URLOfFolder ;
{
NSArray *files = [self contentsOfDirectoryAtURL:URLOfFolder
includingPropertiesForKeys:[NSArray arrayWithObject:NSURLContentModificationDateKey]
options:0
error:nil];
return [files sortedArrayUsingFunction:contentsOfDirSort
context:nil] ;
}
Related
I am working on some file manipulation in iPhone project. Where i need to search files of specific extension. One option is to manually process each file & directory to find.
My Question is, Is there any simple way to do that ?
Thanks
see using NSFileManager you can get the files and bellow the condition with you can get file with particular extension, Its work in Document Directory ..
-(NSArray *)findFiles:(NSString *)extension
{
NSMutableArray *matches = [[NSMutableArray alloc]init];
NSFileManager *manager = [NSFileManager defaultManager];
NSString *item;
NSArray *contents = [manager contentsOfDirectoryAtPath:[NSHomeDirectory() stringByAppendingPathComponent:#"Documents"] error:nil];
for (item in contents)
{
if ([[item pathExtension]isEqualToString:extension])
{
[matches addObject:item];
}
}
return matches;
}
use this array with your searched files.. get the return in NSArray type so use NSArray object to store this data...
i hope this helpful to you...
I have not found any thing which i could say is simple to do that & and finally i have to write my own code to do this. I am posting this here because maybe someone find this help full.
-(void)search{
#autoreleasepool {
NSString *baseDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSFileManager *defFM = [NSFileManager defaultManager];
BOOL isDir = YES;
NSArray *fileTypes = [[NSArray alloc] initWithObjects:#"mp3",#"mp4",#"avi",nil];
NSMutableArray *mediaFiles = [self searchfiles:baseDir ofTypes:fileTypes];
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [docDir stringByAppendingPathComponent:#"playlist.plist"];
if(![defFM fileExistsAtPath:filePath isDirectory:&isDir]){
[defFM createFileAtPath:filePath contents:nil attributes:nil];
}
NSMutableDictionary *playlistDict = [[NSMutableDictionary alloc]init];
for(NSString *path in mediaFiles){
NSLog(#"%#",path);
[playlistDict setValue:[NSNumber numberWithBool:YES] forKey:path];
}
[playlistDict writeToFile:filePath atomically:YES];
[[NSNotificationCenter defaultCenter] postNotificationName:#"refreshplaylist" object:nil];
}
}
Now the recursive Method
-(NSMutableArray*)searchfiles:(NSString*)basePath ofTypes:(NSArray*)fileTypes{
NSMutableArray *files = [[[NSMutableArray alloc]init] autorelease];
NSFileManager *defFM = [NSFileManager defaultManager];
NSError *error = nil;
NSArray *dirPath = [defFM contentsOfDirectoryAtPath:basePath error:&error];
for(NSString *path in dirPath){
BOOL isDir;
path = [basePath stringByAppendingPathComponent:path];
if([defFM fileExistsAtPath:path isDirectory:&isDir] && isDir){
[files addObjectsFromArray:[self searchfiles:path ofType:fileTypes]];
}
}
NSArray *mediaFiles = [dirPath pathsMatchingExtensions:fileTypes];
for(NSString *fileName in mediaFiles){
fileName = [basePath stringByAppendingPathComponent:fileName];
[files addObject:fileName];
}
return files;
}
What you need is a recursive method so that you can process sub-directories. The first of the following methods is public; the other private. Imagine they are implemented as static methods of a class called CocoaUtil:
CocoaUtil.h:
#interface CocoaUtil : NSObject
+ (NSArray *)findFilesWithExtension:(NSString *)extension
inFolder:(NSString *)folder;
#end
CocoaUtil.m:
// Private Methods
#interface CocoaUtil ()
+ (NSArray *)_findFilesWithExtension:(NSString *)extension
inFolder:(NSString *)folder
andSubFolder:(NSString *)subFolder;
#end
#implementation CocoaUtil
+ (NSArray *)findFilesWithExtension:(NSString *)extension
inFolder:(NSString *)folder
{
return [CocoaUtil _findFilesWithExtension:extension
inFolder:folder
andSubFolder:nil];
}
+ (NSArray *)_findFilesWithExtension:(NSString *)extension
inFolder:(NSString *)folder
andSubFolder:(NSString *)subFolder
{
NSMutableArray *found = [NSMutableArray array];
NSString *fullPath = (subFolder != nil) ? [folder stringByAppendingPathComponent:subFolder] : folder;
NSFileManager *fileman = [NSFileManager defaultManager];
NSError *error;
NSArray *contents = [fileman contentsOfDirectoryAtPath:fullPath error:&error];
if (contents == nil)
{
NSLog(#"Failed to find files in folder '%#': %#", fullPath, [error localizedDescription]);
return nil;
}
for (NSString *file in contents)
{
NSString *subSubFolder = subFolder != nil ? [subFolder stringByAppendingPathComponent:file] : file;
fullPath = [folder stringByAppendingPathComponent:subSubFolder];
NSError *error = nil;
NSDictionary *attributes = [fileman attributesOfItemAtPath:fullPath error:&error];
if (attributes == nil)
{
NSLog(#"Failed to get attributes of file '%#': %#", fullPath, [error localizedDescription]);
continue;
}
NSString *type = [attributes objectForKey:NSFileType];
if (type == NSFileTypeDirectory)
{
NSArray *subContents = [CocoaUtil _findFilesWithExtension:extension inFolder:folder andSubFolder:subSubFolder];
if (subContents == nil)
return nil;
[found addObjectsFromArray:subContents];
}
else if (type == NSFileTypeRegular)
{
// Note: case sensitive comparison!
if ([[fullPath pathExtension] isEqualToString:extension])
{
[found addObject:fullPath];
}
}
}
return found;
}
#end
This will return an array containing the full path to every file with the specified file extension. Note that [NSString pathExtension] does not return the . of the file extension so be sure not to pass that in the extension parameter.
Yes we have direct method for NSArray below helps you
NSMutableArray *arrayFiles = [[NSMutableArray alloc] initWithObjects:#"a.png", #"a.jpg", #"a.pdf", #"h.png", #"f.png", nil];
NSLog(#"pathsMatchingExtensions----%#",[arrayFiles pathsMatchingExtensions:[NSArray arrayWithObjects:#"png", nil]]);
//my output is
"a.png",
"h.png",
"f.png"
Like this way you can find your specific file extension
NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
NSFileManager *manager = [NSFileManager defaultManager];
NSDirectoryEnumerator *direnum = [manager enumeratorAtPath:bundleRoot];
NSString *filename;
while ((filename = [direnum nextObject] )) {
if ([filename hasSuffix:#".doc"]) { //change the suffix to what you are looking for
[arrayListofFileName addObject:[filename stringByDeletingPathExtension]];
}
}
Use below code
NSArray *myFiles = [myBundle pathsForResourcesOfType:#"Your File extension"
inDirectory:nil];
I am trying to store some stings into a plist file, the saving process works fine, but these notes should be saved based on a specific date, for example I enter a note on 2 Feb then I need enter another note on 5 Feb, and when I move during these dates my notes should show on these dates. I would be grateful if you help me.
Here is my code:
//Save Setting ///////////////////
- (NSString *) saveFilePath
{
NSArray *pathArray =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSDate *date = [NSDate date];
return [[pathArray objectAtIndex:0] stringByAppendingPathComponent:#"note.plist"];
}
- (void)applicationWillTerminate:(UIApplication *)application
{
NSArray *values = [[NSArray alloc] initWithObjects:saveTextToday.text ,nil];
[values writeToFile:[self saveFilePath] atomically:YES];
[values release];
}
- (void)viewDidLoad
{
////Save Setting /////////////////////////////////////////////////
NSString *myPath = [self saveFilePath];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:myPath];
if (fileExists)
{
NSArray *values = [[NSArray alloc] initWithContentsOfFile:myPath];
saveTextToday.text = [values objectAtIndex:0];
[values release];
}
// notification
UIApplication *myApp = [UIApplication sharedApplication];
// add yourself to the dispatch table
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationWillTerminate:)
name:UIApplicationWillTerminateNotification
object:myApp];
}
It appears you're saving an array to a file, but using a ".plist" file extension. While the file created will be a plist file, there is no date information in the content.
Instead of an array, you could use an NSDictionary. Use the current date as the key, and the array you're using now as the object. Like this:
NSMutableDictionary *myDictionary = [NSMutableDictionary alloc] initWithContentsOfFile:myPath];
NSString *todayKey = [self showPersianFullDate]; // or [self showPersianFullDate:[NSDate date]]
[myDictionary setObject:saveTextToday.text forKey:todayKey];
[myDictionary writeToFile:[self saveFilePath] atomically:YES];
I think what you want to do is use the NSFileManager to find out when the file was saved, like this:
NSString *path = #"the path you've saved you plist to";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSDate *creationDate = nil;
if ([fileManager fileExistsAtPath:path])
{
NSError *error = nil;
NSDictionary *attributes = [fileManager attributesOfItemAtPath:path error:&error];
creationDate = [attributes objectForKey:NSFileCreationDate];
}
creationDate now contains the date when the file was first saved. To get the date when it was last saved, use NSFileModificationDate instead.
Is it possible to upload a .zip file to iCloud, and then have it be synchronized across all of a user's iOS devices?
If so, how would I go about doing this?
If there is any File size limit, then also mention max. file size allowed.
This is how I synchronized zip files with iCloud .
Steps:
1) http://transoceanic.blogspot.in/2011/07/compressuncompress-files-on.html
. Refer this link to download zip api which is having code for zipping and unzipping folder.
2) Now all you need to play with NSData.
3) "MyDocument.h" file
#import <UIKit/UIKit.h>
#interface MyDocument : UIDocument
#property (strong) NSData *zipDataContent;
#end
4)
#import "MyDocument.h"
#implementation MyDocument
#synthesize zipDataContent;
// Called whenever the application reads data from the file system
- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError **)outError
{
self.zipDataContent = [[NSData alloc] initWithBytes:[contents bytes] length:[contents length]];
[[NSNotificationCenter defaultCenter] postNotificationName:#"noteModified" object:self];
return YES;
}
// Called whenever the application (auto)saves the content of a note
- (id)contentsForType:(NSString *)typeName error:(NSError **)outError
{
return self.zipDataContent;
}
#end
5) Now somewhere in your app you need to zip folder and sync with icloud.
-(BOOL)zipFolder:(NSString *)toCompress zipFilePath:(NSString *)zipFilePath
{
BOOL isDir=NO;
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *pathToCompress = [documentsDirectory stringByAppendingPathComponent:toCompress];
NSArray *subpaths;
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:pathToCompress isDirectory:&isDir] && isDir){
subpaths = [fileManager subpathsAtPath:pathToCompress];
} else if ([fileManager fileExistsAtPath:pathToCompress]) {
subpaths = [NSArray arrayWithObject:pathToCompress];
}
zipFilePath = [documentsDirectory stringByAppendingPathComponent:zipFilePath];
//NSLog(#"%#",zipFilePath);
ZipArchive *za = [[ZipArchive alloc] init];
[za CreateZipFile2:zipFilePath];
if (isDir) {
for(NSString *path in subpaths){
NSString *fullPath = [pathToCompress stringByAppendingPathComponent:path];
if([fileManager fileExistsAtPath:fullPath isDirectory:&isDir] && !isDir){
[za addFileToZip:fullPath newname:path];
}
}
} else {
[za addFileToZip:pathToCompress newname:toCompress];
}
BOOL successCompressing = [za CloseZipFile2];
if(successCompressing)
return YES;
else
return NO;
}
-(IBAction) iCloudSyncing:(id)sender
{
//***** PARSE ZIP FILE : Pictures *****
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
if([self zipFolder:#"Pictures" zipFilePath:#"iCloudPictures"])
NSLog(#"Picture Folder is zipped");
ubiq = [[NSFileManager defaultManager]URLForUbiquityContainerIdentifier:nil];
ubiquitousPackage = [[ubiq URLByAppendingPathComponent:#"Documents"] URLByAppendingPathComponent:#"iCloudPictures.zip"];
mydoc = [[MyDocument alloc] initWithFileURL:ubiquitousPackage];
NSString *zipFilePath = [documentsDirectory stringByAppendingPathComponent:#"iCloudPictures"];
NSURL *u = [[NSURL alloc] initFileURLWithPath:zipFilePath];
NSData *data = [[NSData alloc] initWithContentsOfURL:u];
// NSLog(#"%# %#",zipFilePath,data);
mydoc.zipDataContent = data;
[mydoc saveToURL:[mydoc fileURL] forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success)
{
if (success)
{
NSLog(#"PictureZip: Synced with icloud");
}
else
NSLog(#"PictureZip: Syncing FAILED with icloud");
}];
}
6) You can unzip data received from iCloud like this.
- (void)loadData:(NSMetadataQuery *)queryData {
for (NSMetadataItem *item in [queryData results])
{
NSString *filename = [item valueForAttribute:NSMetadataItemDisplayNameKey];
NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
MyDocument *doc = [[MyDocument alloc] initWithFileURL:url];
if([filename isEqualToString:#"iCloudPictures"])
{
[doc openWithCompletionHandler:^(BOOL success) {
if (success) {
NSLog(#"Pictures : Success to open from iCloud");
NSData *file = [NSData dataWithContentsOfURL:url];
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *zipFolder = [documentsDirectory stringByAppendingPathComponent:#"Pics.zip"];
[[NSFileManager defaultManager] createFileAtPath:zipFolder contents:file attributes:nil];
//NSLog(#"zipFilePath : %#",zipFolder);
NSString *outputFolder = [documentsDirectory stringByAppendingPathComponent:#"Pictures"];//iCloudPics
ZipArchive* za = [[ZipArchive alloc] init];
if( [za UnzipOpenFile: zipFolder] ) {
if( [za UnzipFileTo:outputFolder overWrite:YES] != NO ) {
NSLog(#"Pics : unzip successfully");
}
[za UnzipCloseFile];
}
[za release];
NSError *err;
NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:outputFolder error:&err];
if (files == nil) {
NSLog(#"EMPTY Folder: %#",outputFolder);
}
// Add all sbzs to a list
for (NSString *file in files) {
//if ([file.pathExtension compare:#".jpeg" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
NSLog(#" Pictures %#",file);
// NSFileManager *fm = [NSFileManager defaultManager];
// NSDictionary *attributes = [fm fileAttributesAtPath:[NSString stringWithFormat:#"%#/%#",documentsDirectory,file] traverseLink:NO];
//
// NSNumber* fileSize = [attributes objectForKey:NSFileSize];
// int e = [fileSize intValue]; //Size in bytes
// NSLog(#"%#__%d",file,e);
}
}
else
{
NSLog(#"Pictures : failed to open from iCloud");
[self hideProcessingView];
}
}];
}
}
}
In order to enabling Document storage in iCloud your "document" needs to be encapsulated in a UIDocument object.
Because UIDocument links to a file URL, you can easily create a UIDocument pointing to file://myzipfile.zip and then upload a zip document to iCloud.
I hope this helps
Probably this tutorial can help you more:
http://www.raywenderlich.com/6015/beginning-icloud-in-ios-5-tutorial-part-1
it shows me warning that initWithDocPath not found when i want to get private directory content..
+ (NSMutableArray *)loadScaryBugDocs {
NSString *documentsDirectory = [VideoDatabase getPrivateDocsDir];
NSError *error;
NSArray *files =[NSFileManagerdefaultManager]contentsOfDirectoryAtPath:documentsDirectory error:&error];
if (files == nil) {
return nil;
}
NSMutableArray *retval = [NSMutableArray arrayWithCapacity:files.count];
for (NSString *file in files) {
if ([file.pathExtension compare:#"scarybug" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:file];
VideoNotepadViewController *doc = [[[VideoNotepadViewController alloc] initWithDocPath:fullPath] autorelease];
//shows warning here
[retval addObject:doc];
}
}
return retval;
}
You need to implement the initWithDocPath: method in VideoNotepadViewController. Apple doesn't provide a method by that name.
Is there an method to get the contents of a folder in a particular order? I'd like an array of file attribute dictionaries (or just file names) ordered by date modified.
Right now, I'm doing it this way:
get an array with the file names
get the attributes of each file
store the file's path and modified date in a dictionary with the date as a key
Next I have to output the dictionary in date order, but I wondered if there's an easier way? If not, is there a code snippet somewhere which will do this for me?
Thanks.
nall's code above pointed me in the right direction, but I think there are some mistakes in the code as posted above. For instance:
Why is filesAndProperties allocated using NMutableDictonary rather than an NSMutableArray?
NSDictionary* properties = [[NSFileManager defaultManager]
attributesOfItemAtPath:NSFileModificationDate
error:&error];
The code above is passing the wrong parameter for attributesOfItemAtPath - it should be attributesOfItemAtPath:path
Your are sorting the files array, but you should be sorting filesAndProperties.
I have implemented the same, with corrections, and using blocks and posted below:
NSArray *searchPaths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsPath = [searchPaths objectAtIndex: 0];
NSError* error = nil;
NSArray* filesArray = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsPath error:&error];
if(error != nil) {
NSLog(#"Error in reading files: %#", [error localizedDescription]);
return;
}
// sort by creation date
NSMutableArray* filesAndProperties = [NSMutableArray arrayWithCapacity:[filesArray count]];
for(NSString* file in filesArray) {
NSString* filePath = [iMgr.documentsPath stringByAppendingPathComponent:file];
NSDictionary* properties = [[NSFileManager defaultManager]
attributesOfItemAtPath:filePath
error:&error];
NSDate* modDate = [properties objectForKey:NSFileModificationDate];
if(error == nil)
{
[filesAndProperties addObject:[NSDictionary dictionaryWithObjectsAndKeys:
file, #"path",
modDate, #"lastModDate",
nil]];
}
}
// sort using a block
// order inverted as we want latest date first
NSArray* sortedFiles = [filesAndProperties sortedArrayUsingComparator:
^(id path1, id path2)
{
// compare
NSComparisonResult comp = [[path1 objectForKey:#"lastModDate"] compare:
[path2 objectForKey:#"lastModDate"]];
// invert ordering
if (comp == NSOrderedDescending) {
comp = NSOrderedAscending;
}
else if(comp == NSOrderedAscending){
comp = NSOrderedDescending;
}
return comp;
}];
How about this:
// Application documents directory
NSURL *documentsURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSArray *directoryContent = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:documentsURL
includingPropertiesForKeys:#[NSURLContentModificationDateKey]
options:NSDirectoryEnumerationSkipsHiddenFiles
error:nil];
NSArray *sortedContent = [directoryContent sortedArrayUsingComparator:
^(NSURL *file1, NSURL *file2)
{
// compare
NSDate *file1Date;
[file1 getResourceValue:&file1Date forKey:NSURLContentModificationDateKey error:nil];
NSDate *file2Date;
[file2 getResourceValue:&file2Date forKey:NSURLContentModificationDateKey error:nil];
// Ascending:
return [file1Date compare: file2Date];
// Descending:
//return [file2Date compare: file1Date];
}];
Simpler...
NSArray* filelist_sorted;
filelist_sorted = [filelist_raw sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSDictionary* first_properties = [[NSFileManager defaultManager] attributesOfItemAtPath:[NSString stringWithFormat:#"%#/%#", path_thumb, obj1] error:nil];
NSDate* first = [first_properties objectForKey:NSFileModificationDate];
NSDictionary* second_properties = [[NSFileManager defaultManager] attributesOfItemAtPath:[NSString stringWithFormat:#"%#/%#", path_thumb, obj2] error:nil];
NSDate* second = [second_properties objectForKey:NSFileModificationDate];
return [second compare:first];
}];
It's too slow
[[NSFileManager defaultManager]
attributesOfItemAtPath:NSFileModificationDate
error:&error];
Try this code:
+ (NSDate*) getModificationDateForFileAtPath:(NSString*)path {
struct tm* date; // create a time structure
struct stat attrib; // create a file attribute structure
stat([path UTF8String], &attrib); // get the attributes of afile.txt
date = gmtime(&(attrib.st_mtime)); // Get the last modified time and put it into the time structure
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setSecond: date->tm_sec];
[comps setMinute: date->tm_min];
[comps setHour: date->tm_hour];
[comps setDay: date->tm_mday];
[comps setMonth: date->tm_mon + 1];
[comps setYear: date->tm_year + 1900];
NSCalendar *cal = [NSCalendar currentCalendar];
NSDate *modificationDate = [[cal dateFromComponents:comps] addTimeInterval:[[NSTimeZone systemTimeZone] secondsFromGMT]];
[comps release];
return modificationDate;
}
Code does not work in iPhone SDK, full of compilation error. Please find updated code
`
NSInteger lastModifiedSort(id path1, id path2, void* context)
{
int comp = [[path1 objectForKey:#"lastModDate"] compare:
[path2 objectForKey:#"lastModDate"]];
return comp;
}
-(NSArray *)filesByModDate:(NSString*) path{
NSError* error = nil;
NSArray* filesArray = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path
error:&error];
if(error == nil)
{
NSMutableArray* filesAndProperties = [NSMutableArray arrayWithCapacity:[filesArray count]];
for(NSString* imgName in filesArray)
{
NSString *imgPath = [NSString stringWithFormat:#"%#/%#",path,imgName];
NSDictionary* properties = [[NSFileManager defaultManager]
attributesOfItemAtPath:imgPath
error:&error];
NSDate* modDate = [properties objectForKey:NSFileModificationDate];
if(error == nil)
{
[filesAndProperties addObject:[NSDictionary dictionaryWithObjectsAndKeys:
imgName, #"path",
modDate, #"lastModDate",
nil]];
}else{
NSLog(#"%#",[error description]);
}
}
NSArray* sortedFiles = [filesAndProperties sortedArrayUsingFunction:&lastModifiedSort context:nil];
NSLog(#"sortedFiles: %#", sortedFiles);
return sortedFiles;
}
else
{
NSLog(#"Encountered error while accessing contents of %#: %#", path, error);
}
return filesArray;
}
`