Search code examples
iosswifturlrelative-pathnsfilemanager

Swift relativePath property that FileManager.default.enumerator outputs is full path


I want to get relative paths, but I get full paths in the following code. Xcode 14.3

let  homePath = NSHomeDirectory()
let  homeURL = URL(fileURLWithPath: ".", relativeTo: URL(fileURLWithPath: homePath))
guard let  fileEnumeratorIncludingSubFolder = FileManager.default.enumerator(
        at: homeURL,
        includingPropertiesForKeys: [],
        options: [.skipsHiddenFiles, .skipsPackageDescendants])
else { fatalError() }

for case let fileURL as URL in fileEnumeratorIncludingSubFolder {
    print(fileURL.relativePath)  // Expected relative path but full path
}

Solution

  • Try printing out the baseURLs of the URLs you are getting:

    print(fileURL.baseURL)
    

    You should see that these are all nil. Because of this, relativePath returns just returns the path component:

    This is the same as path if baseURL is nil.

    It turns out that giving out absolute URLs is just how enumerator(at:includingPropertiesForKeys:options:errorHandler:) behaves by default.

    Fortunately, there is an additional option that you can pass, so that it producesRelativePathURLs.

    guard let fileEnumeratorIncludingSubFolder = FileManager.default.enumerator(
            at: homeURL,
            includingPropertiesForKeys: [],
            options: [.skipsHiddenFiles, .skipsPackageDescendants, .producesRelativePathURLs]) // here!
    else { fatalError() }