Let’s take a look at this snippet of Swift code:
let homeDirectoryURL = FileManager.default.homeDirectoryForCurrentUser let folderURL = URL(fileURLWithPath: "MyFolder", relativeTo: homeDirectoryURL) let fileURL = URL(fileURLWithPath: "MyFile.txt", relativeTo: folderURL) let absoluteFileURL = fileURL.absoluteURL
At a glance, you would intuitively think
absoluteFileURL is equal to the like of
file://Users/chsxf/MyFolder/MyFile.txt. And so did I.
Obviously, I was wrong. The result is in fact
That created a weird bug in my code while working on The Untitled Project. The FileManager’s
createDirectory(at:withIntermediateDirectories:attributes:) method would only create the last folder relative to my base URL, and not all parent sub-folders, even though the final URL was iteratively built as relative to every one of them.
After digging into this issue for several hours, I started to think there was a bug in the Foundation framework. But, as I was firing the Feedback Assistant to report the issue to Apple, I discovered the
URL(fileURLWithPath:isDirectory:relativeTo:) variant of the
In my case, the right solution was:
let folderURL = URL(fileURLWithPath: "MyFolder", isDirectory: true, relativeTo: homeDirectoryURL)
As always, the bug was between the chair and the keyboard. The problem was that the last path component of my relative URL was considered a file name. And creating another URL relative to this same URL was only replacing that last component.
However, as wrong as I was, URLs and those initialisers can be very counter-intuitive. So I hope this small post will help some of you avoiding this kind of issues.