165
votes

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
10
In Swift 5, to convert string to url is Foundation.URL(string: " "). - Kanishk Gupta

10 Answers

178
votes

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)
128
votes

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
73
votes

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

let path:String = url.path
31
votes

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
23
votes

2020 | SWIFT 5.1:

From STRING to URL:

//ver 1 - better to use it for http/https
//BUT DO NOT use for local paths
let url = URL(string:"https://stackoverflow.com/")

//ver 2 -- for local paths
let url = URL(fileURLWithPath: "//Users/Me/Desktop/Doc.txt")

//ver 3 -- for local folders
let url = URL(fileURLWithPath: "//Users/Me/Desktop", isDirectory: true)

From URL to STRING:

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

BUT value of d will be invisible due to debug process, so...

THE BEST SOLUTION for local files is:

let e = "\(url.path)"                 // "/Users/Me/Desktop/Doc.txt"

The best solution for network adresses is:

let c = url.absoluteString

.path will return only /questions/27062454/converting-url-to-string-and-back-again for http(s) url https://stackguides.com/questions/27062454/converting-url-to-string-and-back-again so for http(s) urls better to use url.absoluteString

16
votes
let url = URL(string: "URLSTRING HERE")
let anyvar =  String(describing: url)
14
votes

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.

9
votes

Swift 3 version code:

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

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
1
votes

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
    }

}