Discover everything about my personal works as a game dev, mostly on Apple platforms

It's Not a Bug. It's a URL Feature

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 file://Users/chsxf/MyFile.txt.

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 URL initializer.

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.