Skip to content

Instantly share code, notes, and snippets.

@chriseidhof
Forked from kostiakoval/:(
Created November 4, 2014 10:41
Show Gist options
  • Save chriseidhof/01003ae72c6072a85f77 to your computer and use it in GitHub Desktop.
Save chriseidhof/01003ae72c6072a85f77 to your computer and use it in GitHub Desktop.
import Foundation
import ImageIO
infix operator >>= { associativity left }
func >>=<A,B>(l: A?, r: A -> B?) -> B? {
if let x = l {
return r(x)
}
return nil
}
func flatMap<A,B>(list: [A], f: A -> B?) -> [B] {
var result : [B] = []
for x in list {
if let value = f(x) {
result.append(value)
}
}
return result
}
func datesFromImagesInDir(dir: String) -> [NSDate] {
let fm = NSFileManager.defaultManager()
var error: NSError?
let df = NSDateFormatter()
df.dateFormat = "yyyy:MM:dd HH:mm:ss"
typealias rn_CGPropDictionary = Dictionary<String, AnyObject>
var dates = [NSDate]()
let options = [(kCGImageSourceShouldCache as String): false]
let dateTimeOriginal = { (exif: rn_CGPropDictionary) in (exif[kCGImagePropertyExifDateTimeOriginal] as? String) }
let exif = { (imageProperties: rn_CGPropDictionary) in imageProperties[kCGImagePropertyExifDictionary] as? rn_CGPropDictionary }
let imageProperties = { CGImageSourceCopyPropertiesAtIndex($0, 0, options) as? rn_CGPropDictionary }
let imageSource = { CGImageSourceCreateWithURL($0, nil) }
let absoluteURL = { (fileName: String) in NSURL(fileURLWithPath: dir)?.URLByAppendingPathComponent(fileName) }
let directoryContents = fm.contentsOfDirectoryAtPath(dir, error: &error) as? [String]
return directoryContents.map {
return flatMap($0) { fileName in
absoluteURL(fileName) >>= imageSource >>= imageProperties >>= exif >>= dateTimeOriginal >>= df.dateFromString
}
} ?? []
}
@chriseidhof
Copy link
Author

This is a bit longer, but almost everything is reusable... lines 36-39 could be pulled out. Also, the two functions are of course reusable across any project.

@rnystrom
Copy link

rnystrom commented Nov 4, 2014

I love it. Didn't think to capture each step in a closure. I was thinking of breaking everything out into their own functions but didn't like that since each step is really only relevant to this implementation. I really appreciate it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment