Swift: How to expand a tilde in a path String

i0S Swift Issue

Question or problem in the Swift programming language:

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, which requires the tilde to be expanded to “/Users//Desktop”.

(This question with a clear problem statement doesn’t exist yet, this should be easily findable. Some similar but not satisfying questions are Can not make path to the file in Swift, Simple way to read local file using Swift?, Tilde-based Paths in Objective-C)

How to solve the problem:

Solution 1:

Tilde expansion

Swift 1
Swift 2
NSString(string: "~/Desktop").stringByExpandingTildeInPath
Swift 3
NSString(string: "~/Desktop").expandingTildeInPath
Home Directory

Additionally you can get the home directory like this (returns a String/String?):


In Swift 3 and OS X 10.12 it’s also possible to use this (returns a URL/URL?):

FileManager.default().homeDirectory(forUser: "")

Edit: In Swift 3.1 this got changed to FileManager.default.homeDirectoryForCurrentUser

Solution 2:

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



URL(fileURLWithPath: NSHomeDirectory()

Solution 3:

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
    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
print("Desktop: \(desktop.path)")

let documents = FileManager.default.urls(
    for: .documentDirectory, in: .userDomainMask
print("Documents: \(documents.path)")

Solution 4:

Swift 4 Extension

public extension String {

    public var expandingTildeInPath: String {
        return NSString(string: self).expandingTildeInPath


Hope this helps!