simons simons - 7 months ago 174
iOS Question

Swift 2 iOS - get file list sorted by creation date - more concise solution?

In my code, which works, I am returning a

containing the names of the files (
) stored in
- ordered by the date last modified.

I believe that I am probably using too many steps and am looking for advice here re how to reduce the code.

In order to achieve the required result currently - I am creating two intermediate dictionaries:
var attributesDictionary: [String : AnyObject]?
var urlDictionary = [NSURL:NSDate]()
. Looping through the initial
I am using two steps -
. I then populate
so that it contains the URL and the value for the key

I feel fairly certain that there should be a way to achieve this result without creating
and without the need for the loop. Perhaps from
directly. Here is my current code:

s were not required as pointed out by Arthur Gevorkyan in the first comment.

func getFileList() -> [String]? {
let directory = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
let properties = [NSURLLocalizedNameKey, NSURLCreationDateKey, NSURLContentModificationDateKey, NSURLLocalizedTypeDescriptionKey]

// no catch required - contentsOfDirectoryAtURL returns nil if there is an error
if let urlArray = try? NSFileManager.defaultManager().contentsOfDirectoryAtURL(directory, includingPropertiesForKeys: properties, options:NSDirectoryEnumerationOptions.SkipsHiddenFiles) {
var attributesDictionary: [String:AnyObject]?
var dateLastModified: NSDate
var urlDictionary = [NSURL:NSDate]()

for URLs in urlArray {
// no catch required - resourceValuesForKeys returns nil if there is an error
attributesDictionary = try? URLs.resourceValuesForKeys(properties)
dateLastModified = attributesDictionary?[NSURLContentModificationDateKey] as! NSDate
urlDictionary[URLs] = dateLastModified
// this approach to sort is used because NSDate cannot be directly compared with </>
return urlDictionary.filter{$0 != nil}.sort{$$1.1) == NSComparisonResult.OrderedDescending }.map{$0.0}.map{$0.lastPathComponent!}
} else {
return nil


A possible solution:

if let urlArray = try? NSFileManager.defaultManager().contentsOfDirectoryAtURL(directory,
    includingPropertiesForKeys: properties, options:.SkipsHiddenFiles) {

    return { url -> (String, NSTimeInterval) in
        var lastModified : AnyObject?
        _ = try? url.getResourceValue(&lastModified, forKey: NSURLContentModificationDateKey)
        return (url.lastPathComponent!, lastModified?.timeIntervalSinceReferenceDate ?? 0)
    .sort({ $0.1 > $1.1 }) // sort descending modification dates
    .map { $0.0 } // extract file names

} else {
    return nil

The array of URLs is mapped to an array of (lastPathComponent, lastModificationDate) tuples first, then sorted according to the last modification date, and finally the path name extracted.

The attributesDictionary can be avoided by using getResourceValue(_ : forKey) to retrieve only the last modification date.