Jernej Strasner

October 01, 2014

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.

publicstructGenericGenerator<T>:GeneratorType,SequenceType{

letenumerator:NSEnumerator

init(_enumerator:NSEnumerator){

self.enumerator=enumerator

}

mutatingpublicfuncnext()->T?{

returnself.enumerator.nextObject()asT?

}

publicfuncgenerate()->GenericGenerator<T>{

returnGenericGenerator<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!

extensionNSDirectoryEnumerator:SequenceType{

publicfuncgenerate()->GenericGenerator<NSURL>{

returnGenericGenerator<NSURL>(self)

}

}

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