Swift’s String.write(toFile:…) can’t handle tildes

let path = "~/Desktop/sigh.txt"
try "WTF?".write(toFile: path, atomically: true, encoding: .utf8)

Result?  Explode:

Error Domain=NSCocoaErrorDomain Code=4 "The folder “sigh.txt” doesn’t exist." UserInfo={NSFilePath=~/Desktop/sigh.txt, NSUserStringVariant=Folder, NSUnderlyingError=0x1018110b0 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}

And since there’s no documentation on that write() method, and this is obviously a perfectly reasonable request that can’t sanely yield that bizarre error message, you could be forgiven for having no idea how to fix this.

Long story short, in macOS Sierra at least that write() method happens to be implemented as NSString’s writeToFile:atomically:encoding:error: method.  If you look at the documentation for that method, it states:

path:  The file to which to write the receiver.  If path contains a tilde (~) character, you must expand it with stringByExpandingTildeInPath before invoking this method.

WTF it can’t actually say that in the Swift method’s documentation (or indeed why it has none at all), or why the exception thrown can’t at least give the real reason, or of course WTF it can’t just do the right thing and handle tildes in the path…  I have no idea.  This smells like a combination of laziness, snafu, and poor judgement in carrying over bad behaviours and design flaws from Objective-C.

So instead you have to do:

try "WTF?".write(toFile: (path as NSString).expandingTildeInPath, atomically: true, encoding: .utf8)

Sigh.

Leave a Reply