In Swift 3.0 (i.e. Xcode 8.0 or Xcode 8.1 beta 1), a call to
fileReferenceURL
does not give a file reference URL anymore... this codeimport Foundation let string = "file:///Users/admin" if let url = NSURL(string: string) { if let ref = url.fileReferenceURL() { print ("ref = (ref)") } }prints
ref = file:///Users/admin/while it should have been printing
ref = file:///.file/id=6571367.437879/as it did, correctly, in Swift 2.2 (and before) in Xcode 7.3.1 for example.
Via Charles Srstka:
.fileReferenceURL
doesn’t exist onURL
. It does exist onNSURL
, but thanks to the bridging magic it returns aURL
, which the ObjC-Swift bridge turns into a normal file path URL.
Frédéric Blondiau has some workarounds, but these are distasteful to me because they rely on the internal details of both NSURLFileResourceIdentifierKey
and file reference URLs.
It seems like the proper short-term solution would be to write some Objective-C code to return an object that is not bridged to URL
. This could probably be the actual NSURL
typed as id
. Or, if you’re going to use an opaque token anyway, another option would be to store bookmark data. I assume that would be slower, though.
Update (2018-09-08): Christian Tietze:
Swift 4.1 has a simpler mechanism to ensure you get a
NSURL
instead of aURL
– the only type that supports file reference URLs as of September 2018, still.if let fileRefURL = (url as NSURL).fileReferenceURL() as NSURL? { print(fileRefURL) }Try that in the Swift 4.1 REPL to see that it works. Whew.
I do understand that there may be reasons to remove
fileReferenceURL
fromURL
and leave it onNSURL
, but when you do invoke it onNSURL
, I think it should at least return anotherNSURL
object that works as expected instead of bridging to Swift’sURL
struct that, for some reason, won’t work.
Update (2019-01-08): Jens Ayton:
No, wait! It actually crashes when you bridge the file reference
NSURL
toURL
.