Checking if a URL is a directory

After some research, this is what I got:

var resultStorage: ObjCBool = false // true or false doesn't matter here, but
                                    // it has to be set before taking its
                                    // address, which we have to do below.

guard FileManager.default.fileExists(atPath: url.path, isDirectory: &resultStorage)
    else { fatalError("Handle case where url is not an existing file.") }

let isDir = resultStorage.boolValue // Finally!

Is this the recommended way to do something as elementary as checking if a given URL is a directory?

I do not know what the recommended way is, but something like

    let isDir = (try url.resourceValues(forKeys: [.isDirectoryKey])).isDirectory

would be an alternative.

3 Likes

Ah, much better, thanks!

I tried the following code (which is, in principle, the code above) and it does not work, files that are not a directory are judged being so:

extension URL {
    var isDirectory: Bool {
       (try? resourceValues(forKeys: [.isDirectoryKey]))?.isDirectory == true
    }
}

So how can I see if an URL points to a directory?

Can you provide an example of those files that are incorrectly judged as folders? Are they packages or what? Other than that, I'd try the two alternatives: one of which is mentioned above: FileManager.fileExists(atPath:isDirectory:) and another which is not: FileManager.attributesOfItem(atPath:). Note that the former method follows symlinks while the other two methods don't.

I tried the following code … and it does not work

This Works on My Machine™. Specifically, the following code running in a command-line tool built with Xcode 13.1 and running on macOS 11.6.1:

import Foundation

extension URL {
    var isDirectory: Bool {
       (try? resourceValues(forKeys: [.isDirectoryKey]))?.isDirectory == true
    }
}

func main() {
    var u = URL(fileURLWithPath: "/System/Library/Kernels/kernel")
    while u.path != "/" {
        print(u.path, "->", u.isDirectory)
        u.deleteLastPathComponent()
    }
}

main()

prints:

/System/Library/Kernels/kernel -> false
/System/Library/Kernels -> true
/System/Library -> true
/System -> true

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

2 Likes

Oh sorry huge (!) mistake on my side. Sorry for this. The code works indeed. Thank you for your time.

Terms of Service

Privacy Policy

Cookie Policy