NSFastEnumeration in Swift

Reading time ~2 minutes

I spent the past few weeks digging into Swift while working on PSPDFKit. Today I was trying to enumerate a directory recursively. I resorted to NSFileManager and its method enumeratorAtURL:includingPropertiesForKeys:options:errorHandler:. It returns an NSDirectoryEnumerator object which supports NSFastEnumeration. That means you can use the for-in loop in Objective-C. Without thinking, I wrote a for-in loop in Swift. Not so fast.

Type ‘NSDirectoryEnumerator’ does not conform to protocol ‘SequenceType’.

Apple should have supported this. So I spent some time browsing trough the Swift headers and with the help of generics I wrote a custom substruct (?) that conforms to the GeneratorType protocol and can be initialized with an object of type NSEnumerator.

public struct GenericGenerator<T> : GeneratorType, SequenceType {
let enumerator: NSEnumerator
init(_ enumerator: NSEnumerator) {
self.enumerator = enumerator
}
mutating public func next() -> T? {
return self.enumerator.nextObject() as T?
}
public func generate() -> GenericGenerator<T> {
return GenericGenerator<T>(self.enumerator)
}
}

In my case I was dealing with NSDirectoryEnumerator which iterates trough NSURL objects. So I wrote an extension to extend it with support for SequenceType. The nice thing is that using for-in in Swift now provides you with NSURL objects!

extension NSDirectoryEnumerator : SequenceType {
public func generate() -> GenericGenerator<NSURL> {
return GenericGenerator<NSURL>(self)
}
}

This generic can now be used to extend any kind of NSEnumerator so you can enjoy clean for-in loops in Swift.

Testing Throwable Methods in Swift 2

With the addition of error handling to Swift 2, we got a way to deal with errors with the nice try/catch exception handling syntax from m...… Continue reading

Singleton Pattern in Swift

Published on June 07, 2014

Smooth gradients on iOS/OSX

Published on January 09, 2014