18

My application is using an NSURL like this:

var url = NSURL(string: "http://www.geonames.org/search.html?q=Aïn+Béïda+Algeria&country=")

When I tried to make a task for getting data from this NSURL like this:

    let task = NSURLSession.sharedSession().dataTaskWithURL(url!, completionHandler: { (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in

        if error == nil {

            var urlContent = NSString(data: data, encoding: NSUTF8StringEncoding)
            println("urlContent \(urlContent!)")
        } else {

            println("error mode")
        }

but I got error when trying to got data from that address, although when I using safari go to link: "http://www.geonames.org/search.html?q=Aïn+Béïda+Algeria&country=" I can see the data. How can I fix that?

Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
Hieu Duc Pham
  • 1,074
  • 1
  • 10
  • 24

1 Answers1

66

Swift 2

let original = "http://www.geonames.org/search.html?q=Aïn+Béïda+Algeria&country="
if let encodedString = original.stringByAddingPercentEncodingWithAllowedCharacters(
    NSCharacterSet.URLFragmentAllowedCharacterSet()),
    url = NSURL(string: encodedString) 
{
    print(url)
}

Encoded URL is now:

"http://www.geonames.org/search.html?q=A%C3%AFn+B%C3%A9%C3%AFda+Algeria&country="

and is compatible with NSURLSession.

Swift 3

let original = "http://www.geonames.org/search.html?q=Aïn+Béïda+Algeria&country="
if let encoded = original.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed),
    let url = URL(string: encoded)
{
    print(url)
}
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
  • why `URLFragmentAllowedCharacterSet`? there is also `URLHostAllowedCharacterSet`, `URLPasswordAllowedCharacterSet`, `URLPathAllowedCharacterSet`, `URLQueryAllowedCharacterSet` and `URLUserAllowedCharacterSet` – fabb May 10 '16 at 07:44
  • @fabb I could have used URLQueryAllowedCharacterSet to the same effect, both sets are complete. The other URL character sets are subsets of these two. – Eric Aya May 10 '16 at 08:14
  • thanks for the info. Have you got some source for that info? – fabb May 10 '16 at 08:27
  • 3
    The source is my own tests: with [this snippet](https://gist.github.com/ericdke/fe3dea5a9b2cac9edd88) I've compared the content of each URL character set. You can see the result [here](https://gist.github.com/ericdke/3b87601583a77b856293ab330b8bd4cc). – Eric Aya May 10 '16 at 08:31
  • 4
    I have two problems with this code snipet: 1. You should *never* encode an entire query string at once. Certain characters are reserved as delimiters between query string parts (&, =, etc.), and if the original strings that make up those query parts contain any of those characters, your approach will break very badly. 2. You should be using NSURLComponents to construct the query string instead of using string concatenation. It is much safer, and it avoids you having to worry about character sets at all. – dgatwood Feb 17 '18 at 09:31