Question or problem with Swift language programming:
I’m quite new to programming a Swift and I’m trying to iterate through the files in a folder.
I took a look at the answer here and tried to translate it to Swift syntax, but didn’t succeed.
let fileManager = NSFileManager.defaultManager() let enumerator:NSDirectoryEnumerator = fileManager.enumeratorAtPath(folderPath) for element in enumerator { //do something }
the error I get is:
Type 'NSDirectoryEnumerator' does not conform to protocol 'SequenceType'
My aim is to look at all the subfolders and files contained into the main folder and find all the files with a certain extension to then do something with them.
How to solve the problem:
Solution 1:
Use the nextObject()
method of enumerator
:
while let element = enumerator?.nextObject() as? String { if element.hasSuffix("ext") { // checks the extension } }
Solution 2:
Nowadays (early 2017) it’s highly recommended to use the – more versatile – URL related API
let fileManager = FileManager.default do { let resourceKeys : [URLResourceKey] = [.creationDateKey, .isDirectoryKey] let documentsURL = try fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) let enumerator = FileManager.default.enumerator(at: documentsURL, includingPropertiesForKeys: resourceKeys, options: [.skipsHiddenFiles], errorHandler: { (url, error) -> Bool in print("directoryEnumerator error at \(url): ", error) return true })! for case let fileURL as URL in enumerator { let resourceValues = try fileURL.resourceValues(forKeys: Set(resourceKeys)) print(fileURL.path, resourceValues.creationDate!, resourceValues.isDirectory!) } } catch { print(error) }
Solution 3:
I couldn’t get pNre’s solution to work at all; the while loop just never received anything. However, I did come across this solution which works for me (in Xcode 6 beta 6, so perhaps things have changed since pNre posted the above answer?):
for url in enumerator!.allObjects { print("\((url as! NSURL).path!)") }
Solution 4:
returns all files in a directory + in subdirectories
import Foundation let path = "" let enumerator = FileManager.default.enumerator(atPath: path) while let filename = enumerator?.nextObject() as? String { print(filename) }
Solution 5:
Swift3 + absolute urls
extension FileManager { func listFiles(path: String) -> [URL] { let baseurl: URL = URL(fileURLWithPath: path) var urls = [URL]() enumerator(atPath: path)?.forEach({ (e) in guard let s = e as? String else { return } let relativeURL = URL(fileURLWithPath: s, relativeTo: baseurl) let url = relativeURL.absoluteURL urls.append(url) }) return urls } }
Based on code from @user3441734