Search code examples
iosswiftsubdirectory

Listing (only) the subfolders within a folder -- Swift 3.0 / iOS 10


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!


Solution

  • 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 :)