NSURL.URLByResolvingSymlinksInPath does not work for /tmp, /var. Is there a workaround?
(code examples in macruby syntax)
If I create an url with:
u1 = NSURL.fileURLWithPath('/tmp')
and then try to create an url with symlinks resolved:
u2=u1.URLByResolvingSymlinksInPath
I get back /tmp:
irb(main):010:0> u2.pathComponents
=> ["/", "tmp"]
This is a problem because if I create an NSDirectoryEnumerator with this NSURL (or /var or /etc), and prefetch the NSURLParentDirectoryURLKey, the NSURLs returned will have path /private/tmp/...
I need to get the components of the directory paths that are relative to the root of the NSDirectoryEnumerator. Is there a robust way to do this, other than hardcoded detection of the spe开发者_如何学运维cial cases I know about (which so far are /tmp, /var, and /etc)?
Is anyone aware of other "special" directories on which URLByResolvingSymlinksInPath doesn't work?
I was never able to find a complete answer to this. For my case, I added a method to NSURL that handles /tmp, /var & /etc:
class NSURL
def URLByResolvingSymlinksInPathIncludingPrivate
url = self.URLByResolvingSymlinksInPath
parts = url.pathComponents
if (parts.first == '/') && ['tmp', 'var', 'etc'].include?(parts[1])
url = NSURL.fileURLWithPathComponents(['/', 'private'] + parts[1..-1])
end
url
end
end
I decided it was best to add an explicit method and not monkeypatch URLByResolvingSymlinksInPath.
Matt Gallagher - Resolving a path containing a mixture of aliases and symlinks
StackOverflow - Resolving Finder alias files
My own solution only resolves symlinks, but not alias files.
extension URL {
func resolveSymlinks() -> URL? {
let fm = FileManager.default
var url = self.resolvingSymlinksInPath()
for _ in 0..<100 { // prevent infinite loop
guard let target: String = try? fm.destinationOfSymbolicLink(atPath: url.path) else {
return url
}
if target.hasPrefix("/") {
url = URL(fileURLWithPath: target)
continue
}
url = url.deletingLastPathComponent().appendingPathComponent(target)
}
return nil
}
}
// URL(fileURLWithPath: "/tmp").resolveSymlinks()
// file:///private/tmp/
精彩评论