Iterate through files in a folder and its subfolders using Swift's FileManager
Use the nextObject()
method of enumerator
:
while let element = enumerator?.nextObject() as? String {
if element.hasSuffix("ext") { // checks the extension
}
}
Iterating through files in a folder with nested folders - Cocoa
Use NSDirectoryEnumerator
to recursively enumerate files and directories under the directory you want, and ask it to tell you whether it is a file or directory. The following is based on the example listed at the documentation for -[NSFileManager enumeratorAtURL:includingPropertiesForKeys:options:errorHandler:]
:
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *directoryURL = … // URL pointing to the directory you want to browse
NSArray *keys = [NSArray arrayWithObject:NSURLIsDirectoryKey];
NSDirectoryEnumerator *enumerator = [fileManager
enumeratorAtURL:directoryURL
includingPropertiesForKeys:keys
options:0
errorHandler:^BOOL(NSURL *url, NSError *error) {
// Handle the error.
// Return YES if the enumeration should continue after the error.
return YES;
}];
for (NSURL *url in enumerator) {
NSError *error;
NSNumber *isDirectory = nil;
if (! [url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:&error]) {
// handle error
}
else if (! [isDirectory boolValue]) {
// No error and it’s not a directory; do something with the file
}
}
listing all files in a folder recursively with swift
FileManager
has also a method for a deep search: enumerator(at:includingPropertiesForKeys:options:errorHandler:)
To get only the files you have to iterate the enumerator and filter the files
let url = URL(fileURLWithPath: "/path/to/directory")
var files = [URL]()
if let enumerator = FileManager.default.enumerator(at: url, includingPropertiesForKeys: [.isRegularFileKey], options: [.skipsHiddenFiles, .skipsPackageDescendants]) {
for case let fileURL as URL in enumerator {
do {
let fileAttributes = try fileURL.resourceValues(forKeys:[.isRegularFileKey])
if fileAttributes.isRegularFile! {
files.append(fileURL)
}
} catch { print(error, fileURL) }
}
print(files)
}
It's highly recommended to use URLs rather than string paths.
Cocoa/Swift: Loop through names of folder in path
I use enumeratorAtURL
. Here's some code that shows an example of how to print the directories in the user's home directory.
if let dirURL = NSURL(fileURLWithPath: NSHomeDirectory()) {
let keys = [NSURLIsDirectoryKey, NSURLLocalizedNameKey]
let fileManager = NSFileManager.defaultManager()
let enumerator = fileManager.enumeratorAtURL(
dirURL,
includingPropertiesForKeys: keys,
options: (NSDirectoryEnumerationOptions.SkipsPackageDescendants |
NSDirectoryEnumerationOptions.SkipsSubdirectoryDescendants |
NSDirectoryEnumerationOptions.SkipsHiddenFiles),
errorHandler: {(url, error) -> Bool in
return true
}
)
while let element = enumerator?.nextObject() as? NSURL {
var getter: AnyObject?
element.getResourceValue(&getter, forKey: NSURLIsDirectoryKey, error: nil)
let isDirectory = getter! as Bool
element.getResourceValue(&getter, forKey: NSURLLocalizedNameKey, error: nil)
let itemName = getter! as String
if isDirectory {
println("\(itemName) is a directory in \(dirURL.absoluteString)")
//do something with element here.
}
}
}
Get list of files at path swift
I think this may be possible by implementing an extension to NSFileManager that implements the SequenceType protocol. But you could easily convert your code to using a while loop:
let filemanager:FileManager = FileManager()
let files = filemanager.enumerator(atPath: NSHomeDirectory())
while let file = files?.nextObject() {
print(file)
}
Get Subdirectories using Swift
There is no need to use a deep enumeration. Just get contentsOfDirectoryAtURL and filter the urls returned which are directories.
Xcode 11.4• Swift 5.2
extension URL {
func subDirectories() throws -> [URL] {
// @available(macOS 10.11, iOS 9.0, *)
guard hasDirectoryPath else { return [] }
return try FileManager.default.contentsOfDirectory(at: self, includingPropertiesForKeys: nil, options: [.skipsHiddenFiles]).filter(\.hasDirectoryPath)
}
}
usage:
do {
let documentsDirectory = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
let url = documentsDirectory.appendingPathComponent("pictures", isDirectory: true)
if !FileManager.default.fileExists(atPath: url.path) {
try FileManager.default.createDirectory(at: url, withIntermediateDirectories: false, attributes: nil)
}
let subDirs = try documentsDirectory.subDirectories()
print("sub directories", subDirs)
subDirs.forEach { print($0.lastPathComponent) }
} catch {
print(error)
}
Get the name of file(s) within last directory and the full directory path using Swift
As element
is an URL, if you're interested in the full path name rather than the last component, just go for:
var nextObject = element.absoluteURL // instead of .lastPathComponent
or just
var nextObject = element.path // or even relativePath
Related Topics
Using a Type Variable in a Generic
Realitykit VS Scenekit VS Metal - High-Quality Rendering
How to Compare One Value Against Multiple Values - Swift
How to Make a Random Color With Swift
How to Round a Double to the Nearest Int in Swift
Use Binding≪Int≫ With a Textfield Swiftui
Swift Dictionary Get Key For Value
Swift Lazy Instantiating Using Self
Printing a Variable Memory Address in Swift
Uialertcontroller - Add Custom Views to Actionsheet
What Does "@Uiapplicationmain" Mean
Whither Dispatch_Once in Swift 3
Rounding a Double Value to X Number of Decimal Places in Swift
How to Deal With @Objc Inference Deprecation With #Selector() in Swift 4