Search code examples
swiftfilepathenumerator

Get fullpath or convert to fullpath


When using

let directoryEnumerator = FileManager().enumerator(at: ...

in Swift 3, I get all files from the folder, e.g.

"file:///Volumes/MacOS/fasttemp/Fotos/"

The results are not including the leading path (here "/Volumes/MacOS"). So I get

"file:///fasttemp/Fotos/2005/"

How can I get the fullpath (directly from the enumerator) or convert them. I want to use URL functions, not string function manipulating by assumptions.


Solution

  • If "MacOS" is the name of your current startup disk then "/Volumes/MacOS" is a symbolic link to "/", so both "/fasttemp/Fotos/2005/" and "/Volumes/MacOS/fasttemp/Fotos/" are absolute paths to the same file.

    In order to get a unique file name representation you can query a URL for its canonical path. Example:

    let url = URL(fileURLWithPath: "/Volumes/MacOS/Applications/Utilities/")
    if let cp = (try? url.resourceValues(forKeys: [.canonicalPathKey]))?.canonicalPath {
        print(cp)
    }
    // Output: "/Applications/Utilities"
    

    This requires macOS 10.12/iOS 10 or later. On older systems you can use the realpath() system call:

    if let rp = url.withUnsafeFileSystemRepresentation ({ realpath($0, nil) }) {
        let fullUrl = URL(fileURLWithFileSystemRepresentation: rp, isDirectory: true, relativeTo: nil)
        free(rp)
        print(fullUrl.path)
    }
    // Output: "/Applications/Utilities"