swiftnsurlrequestpercent-encoding

Wrong NSURLQueryItem percentage encoding for Google CSE


I'm writing app using Google custom search engine.

I received my search engine ID XXXXXXXX219143826571:7h9XXXXXXX (most interesting part bold).

Now I'm trying to use NSURLQueryItem to embed my ID into URL by using:

let params = ["cx" : engineID,...]
...
components.queryItems = parameters.map {
    NSURLQueryItem(name: String($0), value: String($1))
}

It should percentage escape item to XXXXXXXX219143826571%3A7h9XXXXXXX (This value I'm getting when using Google APIs explorer while testing, it shows url dress that was used). It is not doing it. I'm getting url without escaping, no changes. If I use escaped string as engine ID in this mapping, I'm getting escaped string XXXXXXXX219143826571%253A7h9XXXXXXX (additional '25' is added to query).

Can someone tell me how to fix it? I don't want to use String and then convert it to URL by NSURL(string: str)!. It is not elegant.

Edit:

I'm using app Info.plist to save ID and I retrieve it by calling:

String(NSBundle.mainBundle().objectForInfoDictionaryKey("ApiKey")!)

Solution

  • Colons are allows in the query part of a URL string. There should be no need to escape them.

    Strictly speaking, the only things that absolutely have to be encoded in that part of a URL are ampersands, hash marks (#), and (assuming you're doing a GET query with form encoding) equals signs. However, question marks in theory may cause problems, slashes are technically not allowed (but work just fine), and semicolons are technically allowed (but again, work in practice).

    Colons, AFAIK, only have special meaning in the context of paths (if the OS treats it as a path separator) and in that it separates the scheme (protocol) from the rest of the URL.

    So don't worry about the colon being unencoded unless the Google API barfs for some reason.