214

So I have converted an NSURL to a String. So if I println it looks like file:///Users/... etc.

Later I want this back as an NSURL so I try and convert it back as seen below, but I lose two of the forward slashes that appear in the string version above, that in turn breaks the code as the url is invalid.

Why is my conversion back to NSURL removing two forward slashes from the String I give it, and how can I convert back to the NSURL containing three forward slashes?

var urlstring: String = recordingsDictionaryArray[selectedRow]["path"] as String
println("the url string = \(urlstring)")
// looks like file:///Users/........etc
var url = NSURL.fileURLWithPath(urlstring)
println("the url = \(url!)")
// looks like file:/Users/......etc
1
  • In Swift 5, to convert string to url is Foundation.URL(string: " "). Commented Nov 11, 2019 at 6:41

10 Answers 10

227

In Swift 5, Swift 4 and Swift 3 To convert String to URL:

URL(string: String)

or,

URL.init(string: "yourURLString")

And to convert URL to String:

URL.absoluteString

The one below converts the 'contents' of the url to string

String(contentsOf: URL)
Sign up to request clarification or add additional context in comments.

4 Comments

The second part is incorrect. String(contentsOf: URL) returns the actual payload of that resource, not the URL in string format. Use URL.absoluteString to get the string version of the URL. developer.apple.com/reference/foundation/nsurl/…
You're making the same mistake as in stackoverflow.com/a/39967995/2227743 where you conflate converting the URL itself to a string with converting the downloaded content to a String. You should remove this part of your answer because it is completely wrong (or off-topic, but in the end it's wrong because it doesn't answer the question).
35+ people found this useful and upvoted it, I would rather keep it as is.
I got burned using fileManager.fileExists(atPath: dbPath.absoluteString), because the conversion from URL preserved the escaped spaces, like this: Application%20Support instead of Application Support, and it returned false. It didn't do this with dbPath.path. Just something to be aware of.
130

fileURLWithPath() is used to convert a plain file path (e.g. "/path/to/file") to an URL. Your urlString is a full URL string including the scheme, so you should use

let url = NSURL(string: urlstring)

to convert it back to NSURL. Example:

let urlstring = "file:///Users/Me/Desktop/Doc.txt"
let url = NSURL(string: urlstring)
println("the url = \(url!)")
// the url = file:///Users/Me/Desktop/Doc.txt

2 Comments

Excellent. Or now in Swift: URL(string: urlstring)
Maybe you need "urlstring.removingWhitespaces()", because URL(string don't have the capacity to work when the string has spaces
77

There is a nicer way of getting the string version of the path from the NSURL in Swift:

let path:String = url.path

2 Comments

but it will return only /questions/27062454/converting-url-to-string-and-back-again for url https://stackoverflow.com/questions/27062454/converting-url-to-string-and-back-again
This is actually really useful if you want to use the path for some of the other FileManager methods that need a string path. They don't like the file:// format.
60

2021 | SWIFT 5.1:

FOR LOCAL PATHS

String --> URL :

let url1 = URL(fileURLWithPath: "//Users/Me/Desktop/Doc.txt")
let url2 = URL(fileURLWithPath: "//Users/Me/Desktop", isDirectory: true)

// !!!!!NEVER DO THIS FOR LOCAL PATHS!!!!!!
let url3 = URL(string: "file:///Users/Me/Desktop/Doc.txt")!
// !!!!!NEVER DO THIS!!!!!!

URL --> String :

let a = String(describing: url1)  // "file:////Users/Me/Desktop/Doc.txt"
let b = "\(url1)"                 // "file:////Users/Me/Desktop/Doc.txt"
let c = url1.absoluteString       // "file:////Users/Me/Desktop/Doc.txt"

// Best solution in most cases
let d = url1.path                 // "/Users/Me/Desktop/Doc.txt"

FOR INTERNET URLs

String --> URL :

let url = URL(string: "https://stackoverflow.com/questions/27062454/converting-url-to-string-and-back-again")!

URL --> String :

url.absoluteString // https://stackoverflow.com/questions/27062454/converting-url-to-string-and-back-again

url.path           // /questions/27062454/converting-url-to-string-and-back-again

7 Comments

By the way, the URL.path is now deprecated from iOS 16.2 and above. What could be the replacement for it?
@Goppinath have no idea, I'm working with macOS =)
Accessing the path is not deprecated - only creating a new URL from a string using path is.
@clearlight because of this initialisation must be used only for internet URLs. If you will use it with local path it can do not work in some cases because of incorrect initialisation. It is for some reason created init(fileURLWithPath: String) except init(string: String) :) If you want to know details - you always can check official documentation. Also the second one init creates nullable URL this is also bad thing when you are able to init not-nullable URL without loose of anything :)
@Goppinath probably path(percentEncoded:) is a new way to go.
|
35

NOTICE: pay attention to the url, it's optional and it can be nil. You can wrap your url in the quote to convert it to a string. You can test it in the playground.
Update for Swift 5, Xcode 11:

import Foundation

let urlString = "http://ifconfig.me"
// string to url
let url = URL(string: urlString)
//url to string
let string = "\(url)"
// if you want the path without `file` schema
// let string = url.path

1 Comment

It should be noted that this returns also the scheme prefix (think file:///Users/foo). While if just the absolute path is needed (think /Users/foo), then url.path should be used as in @iphaaw's answer below.
16
let url = URL(string: "URLSTRING HERE")
let anyvar =  String(describing: url)

Comments

13

Swift 3 (forget about NSURL).

let fileName = "20-01-2017 22:47"
let folderString = "file:///var/mobile/someLongPath"

To make a URL out of a string:

let folder: URL? = Foundation.URL(string: folderString)
// Optional<URL>
//  ▿ some : file:///var/mobile/someLongPath

If we want to add the filename. Note, that appendingPathComponent() adds the percent encoding automatically:

let folderWithFilename: URL? = folder?.appendingPathComponent(fileName)
// Optional<URL>
//  ▿ some : file:///var/mobile/someLongPath/20-01-2017%2022:47

When we want to have String but without the root part (pay attention that percent encoding is removed automatically):

let folderWithFilename: String? = folderWithFilename.path
// ▿ Optional<String>
//  - some : "/var/mobile/someLongPath/20-01-2017 22:47"

If we want to keep the root part we do this (but mind the percent encoding - it is not removed):

let folderWithFilenameAbsoluteString: String? = folderWithFilenameURL.absoluteString
// ▿ Optional<String>
//  - some : "file:///var/mobile/someLongPath/20-01-2017%2022:47"

To manually add the percent encoding for a string:

let folderWithFilenameAndEncoding: String? = folderWithFilename.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
// ▿ Optional<String>
//  - some : "/var/mobile/someLongPath/20-01-2017%2022:47"

To remove the percent encoding:

let folderWithFilenameAbsoluteStringNoEncodig: String? = folderWithFilenameAbsoluteString.removingPercentEncoding
// ▿ Optional<String>
//  - some : "file:///var/mobile/someLongPath/20-01-2017 22:47"

The percent-encoding is important because URLs for network requests need them, while URLs to file system won't always work - it depends on the actual method that uses them. The caveat here is that they may be removed or added automatically, so better debug these conversions carefully.

Comments

8

Swift 3 version code:

let urlString = "file:///Users/Documents/Book/Note.txt"
let pathURL = URL(string: urlString)!
print("the url = " + pathURL.path)

Comments

6

Swift 5.

To convert a String to a URL:

let stringToURL = URL(string: "your-string")

To convert a URL to a String:

let urlToString = stringToURL?.absoluteString

Comments

1

Swift 3 used with UIWebViewDelegate shouldStartLoadWith

  func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {

    let urlPath: String = (request.url?.absoluteString)!
    print(urlPath)
    if urlPath.characters.last == "#" {
        return false
    }else{
        return true
    }

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.