I'm attempting to get a list of all subfolders within a folder (the app's Documents
directory, in the example below). The code below successfully finds everything in the folder (files + folders both), and also finds the files with the specified .text
extension, but I'm failing to narrow the results to just a list of the subdirectories.
let filemgr = FileManager.default
var dirPaths = filemgr.urls(for: .documentDirectory, in: .userDomainMask)
myDocumentsDirectory = dirPaths[0]
var r = "Directory Listing:\n------------------\n" // r = will be returned (or displayed in this case)
do {
let directoryContents = try FileManager.default.contentsOfDirectory(at: myDocumentsDirectory, includingPropertiesForKeys: nil, options: [])
// all files -- works fine
let allFileNames = directoryContents.map{ $0.deletingPathExtension().lastPathComponent }
r += "All file names:\n\(allFileNames)\n\n"
// filtering for text files -- also works fine
let textFiles = directoryContents.filter{ $0.pathExtension == "text" }
let textFileNames = textFiles.map{ $0.deletingPathExtension().lastPathComponent }
r += "text file list:\n\(textFileNames)\n\n"
// Look for folders within the folder -- fails, nothing returned
let subdirs = directoryContents.filter{ !$0.isFileURL }
let subdirNames = subdirs.map{ $0.deletingPathExtension().lastPathComponent }
r += "Subdirectories:\n\(subdirNames)\n\n"
textView.text = r
} catch let error as NSError {
print(error.localizedDescription)
I can pick up all the directories by setting the filter to
$0.pathExtension == ""
but that also picks up any files in the directory with no extension -- i.e. it correctly excludes foo.bar
but incorrectly includes the file foo
along with the folders, and that isn't what I need -- has to be only the directories & nothing more.
Also, I'm not trying to look deeper into sub-folders within sub-folders -- just the ones "here" is all I'm looking for.
Any suggestions will be much appreciated!
PHP using scandir() to find folders in a directory The scandir function is an inbuilt function that returns an array of files and directories of a specific directory. It lists the files and directories present inside the path specified by the user.
The dir command displays a list of files and subdirectories in a directory. With the /S option, it recurses subdirectories and lists their contents as well. Options listed below may be preset in the DIRCMD environment variable.
You can pass URLResourceKey.isDirectoryKey
to the includingPropertiesForKeys
parameter in your contentsOfDirectory
method call on line 6. This should return that particular attribute for all your returned URLs. Then, you can check the attribute to see if each URL is for a directory or a file ...
If you are wondering how to get at the attributes for the fetched URLs, then take a look at the resourceValues
method for the URL
class :)
Fahim's answer, specifically the resourceValues
method for the URL
class, is what I needed; for completeness & to help out anybody who finds this question later, here is the final code that gets exactly what I wanted, while keeping the same basic structure:
let filemgr = FileManager.default
var dirPaths = filemgr.urls(for: .documentDirectory, in: .userDomainMask)
myDocumentsDirectory = dirPaths[0]
do {
let directoryContents = try FileManager.default.contentsOfDirectory(at: myDocumentsDirectory, includingPropertiesForKeys: nil, options: [])
let onlyFileNames = directoryContents.filter{ !$0.hasDirectoryPath }
let onlyFileNamesStr = onlyFileNames.map { $0.lastPathComponent }
let subdirs = directoryContents.filter{ $0.hasDirectoryPath }
let subdirNamesStr = subdirs.map{ $0.lastPathComponent }
// now do whatever with the onlyFileNamesStr & subdirNamesStr
} catch let error as NSError {
print(error.localizedDescription)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With