How to encode a URL in Swift [duplicate]

This is my URL.

The problem is, that the address field is not being appended to urlpath.

Does anyone know why that is?

var address:string
address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
let urlpath = NSString(format: "http://maps.googleapis.com/maps/api/geocode/json?address="+"\(address)")

Solution 1:

Swift 4.2

var urlString = originalString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)

Swift 3.0

var address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
let escapedAddress = address.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
let urlpath = String(format: "http://maps.googleapis.com/maps/api/geocode/json?address=\(escapedAddress)")

Use stringByAddingPercentEncodingWithAllowedCharacters:

var escapedAddress = address.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())

Use stringByAddingPercentEscapesUsingEncoding: Deprecated in iOS 9 and OS X v10.11

var address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
var escapedAddress = address.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
let urlpath = NSString(format: "http://maps.googleapis.com/maps/api/geocode/json?address=\(escapedAddress)")

Solution 2:

If it's possible that the value that you're adding to your URL can have reserved characters (as defined by section 2 of RFC 3986), you might have to refine your percent-escaping. Notably, while & and + are valid characters in a URL, they're not valid within a URL query parameter value (because & is used as delimiter between query parameters which would prematurely terminate your value, and + is translated to a space character). Unfortunately, the standard percent-escaping leaves those delimiters unescaped.

Thus, you might want to percent escape all characters that are not within RFC 3986's list of unreserved characters:

Characters that are allowed in a URI but do not have a reserved purpose are called unreserved. These include uppercase and lowercase letters, decimal digits, hyphen, period, underscore, and tilde.

     unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"

Later, in section 3.4, the RFC further contemplates adding ? and / to the list of allowed characters within a query:

The characters slash ("/") and question mark ("?") may represent data within the query component. Beware that some older, erroneous implementations may not handle such data correctly when it is used as the base URI for relative references (Section 5.1), apparently because they fail to distinguish query data from path data when looking for hierarchical separators. However, as query components are often used to carry identifying information in the form of "key=value" pairs and one frequently used value is a reference to another URI, it is sometimes better for usability to avoid percent- encoding those characters.

Nowadays, you'd generally use URLComponents to percent escape the query value:

var address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
var components = URLComponents(string: "http://maps.googleapis.com/maps/api/geocode/json")!
components.queryItems = [URLQueryItem(name: "address", value: address)]
let url = components.url!

By the way, while it's not contemplated in the aforementioned RFC, section 5.2, URL-encoded form data, of the W3C HTML spec says that application/x-www-form-urlencoded requests should also replace space characters with + characters (and includes the asterisk in the characters that should not be escaped). And, unfortunately, URLComponents won't properly percent escape this, so Apple advises that you manually percent escape it before retrieving the url property of the URLComponents object:

// configure `components` as shown above, and then:

components.percentEncodedQuery = components.percentEncodedQuery?.replacingOccurrences(of: "+", with: "%2B")
let url = components.url!

For Swift 2 rendition, where I manually do all of this percent escaping myself, see the previous revision of this answer.

Solution 3:

Swift 3:

let escapedString = originalString.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)