Reputation:
Assume a file URL
containing /Users/me/a/b
. Is there a better method than a naive string replace using NSHomeDirectory()
to get the short form ~/a/b
?
This is what I'm currently using
.replacingOccurrences(of: NSHomeDirectory(), with: "~", options: .anchored, range: nil)
PS: No NSString
casting!
Upvotes: 5
Views: 1000
Reputation: 3334
I noticed this question doesn't have an accepted answer yet, and I ran into the same issue. I tried the NSString
methods, but those didn't work in a sandboxed context anyway, and the getpwuid
method felt… wrong. So here's a pure Swift solution that's only really hardcoded insofar as it assumes the sandbox root to share the first 3 path components (/
, Users
, your username) with your actual home directory:
extension URL {
var pathAbbreviatingWithTilde: String {
// find home directory path (more difficulty because we're sandboxed, so it's somewhere deep in our actual home dir)
let sandboxedHomeDir = FileManager.default.homeDirectoryForCurrentUser
let components = sandboxedHomeDir.pathComponents
guard components.first == "/" else { return path }
let homeDir = "/" + components.dropFirst().prefix(2).joined(separator: "/")
// replace home dir in path with tilde for brevity and aesthetics
guard path.hasPrefix(homeDir) else { return path }
return "~" + path.dropFirst(homeDir.count)
}
}
Upvotes: 0
Reputation: 6732
If you are in Sandboxed app then usage of getpwuid
function is needed.
extension FileManager {
/// Returns path to real home directory in Sandboxed application
public var realHomeDirectory: String? {
if let home = getpwuid(getuid()).pointee.pw_dir {
return string(withFileSystemRepresentation: home, length: Int(strlen(home)))
}
return nil
}
}
Example usage:
func configure(url: URL) {
...
var directory = url.path.deletingLastPathComponent
toolTip = url.path
if let homeDir = FileManager.default.realHomeDirectory {
// FYI: `url.path.abbreviatingWithTildeInPath` not working for sandboxed apps.
let abbreviatedPath = url.path.replacingFirstOccurrence(of: homeDir, with: "~")
directory = abbreviatedPath.deletingLastPathComponent
toolTip = abbreviatedPath
}
directoryLabel.text = directory
}
More about getpwuid
function: How do I get the users home directory in a sandboxed app?
Result of usage in NSView
:
Upvotes: 3
Reputation: 802
NSPathUtilities - (NSString *)stringByAbbreviatingWithTildeInPath; - (NSString *)stringByExpandingTildeInPath;
[blueprintsDict writeToFile: [[NSString stringWithFormat:@"~/MbPatchBlueprints.plist"] stringByExpandingTildeInPath] atomically:YES];
Upvotes: 0
Reputation: 2563
How about converting to NSString and then abbreviating it with:
var path = url.path as NSString!
var abbrevPath=path?.abbreviatingWithTildeInPath
Upvotes: 0