How can I expand a path String with a tilde in Swift? I have a string like \"~/Desktop\"
and I\'d like to use this path with the NSFileManager
methods,
Return string:
func expandingTildeInPath(_ path: String) -> String {
return path.replacingOccurrences(of: "~", with: FileManager.default.homeDirectoryForCurrentUser.path)
}
Return URL:
func expandingTildeInPath(_ path: String) -> URL {
return URL(fileURLWithPath: path.replacingOccurrences(of: "~", with: FileManager.default.homeDirectoryForCurrentUser.path))
}
If OS less than 10.12, replace
FileManager.default.homeDirectoryForCurrentUser
with
URL(fileURLWithPath: NSHomeDirectory()
Here is a solution that does not depend on the NSString
class and works with Swift 4:
func absURL ( _ path: String ) -> URL {
guard path != "~" else {
return FileManager.default.homeDirectoryForCurrentUser
}
guard path.hasPrefix("~/") else { return URL(fileURLWithPath: path) }
var relativePath = path
relativePath.removeFirst(2)
return URL(fileURLWithPath: relativePath,
relativeTo: FileManager.default.homeDirectoryForCurrentUser
)
}
func absPath ( _ path: String ) -> String {
return absURL(path).path
}
Test code:
print("Path: \(absPath("~"))")
print("Path: \(absPath("/tmp/text.txt"))")
print("Path: \(absPath("~/Documents/text.txt"))")
The reason for splitting the code into two methods is that nowadays you rather want URLs when working with files and folders and not string paths (all new APIs use URLs for paths).
By the way, if you just want to know the absolute path of ~/Desktop
or ~/Documents
and similar folders, there's an even easier way for that:
let desktop = FileManager.default.urls(
for: .desktopDirectory, in: .userDomainMask
)[0]
print("Desktop: \(desktop.path)")
let documents = FileManager.default.urls(
for: .documentDirectory, in: .userDomainMask
)[0]
print("Documents: \(documents.path)")
Swift 4 Extension
public extension String {
public var expandingTildeInPath: String {
return NSString(string: self).expandingTildeInPath
}
}
"~/Desktop".stringByExpandingTildeInPath
NSString(string: "~/Desktop").stringByExpandingTildeInPath
NSString(string: "~/Desktop").expandingTildeInPath
Additionally you can get the home directory like this (returns a String
/String?
):
NSHomeDirectory()
NSHomeDirectoryForUser("<User>")
In Swift 3 and OS X 10.12 it's also possible to use this (returns a URL
/URL?
):
FileManager.default().homeDirectoryForCurrentUser
FileManager.default().homeDirectory(forUser: "<User>")
Edit: In Swift 3.1 this got changed to FileManager.default.homeDirectoryForCurrentUser