Following on from escaping URL paths, it's time to take a look at query strings. Consider this fairly "complete" URL:
scheme://host/path?query#fragment
Since the query comes pretty late on, most of the reserved characters are no longer reserved at this point. e.g. having a / or ? symbol as part of the query is just dandy, since there's already been a ? to indicate the beginning of the query.
The obvious exception is # since it follows the query to indicate the fragment component. As it happens, ‑stringByAddingPercentEscapesUsingEncoding: leaves most reserved URL characters untouched, except for # which it does escape (no, I don't understand why!). This would make it ideal for URL queries apart from one major caveat:
Many web servers are set up to interpret + characters when in a query as being a space. If a + character makes it through unencoded, it could well be mistaken for a space, and so instead should be encoded as %2B. So to handle this, we want a routine like so:
Query Parameters
There's also the complication that queries are often structured in a dictionary-like format to represent multiple parameters, like so:
scheme://host/path?key=value&key2=value2#fragment
The ; character is also permitted to be used to the same effect as & in the example above.
If you want to avoid a plain query possibly being mistook as a series of parameters, it's likely safest to escape, =, ; and & characters too!
But what if you want to programatically construct a URL containing query parameters? Don't worry, I've got your back again, with KSURLQueryUtilities. There you'll find a selection of methods to go between URL (and their strings), and NSDictionary.
The important bit is — in a similar fashion to above — to escape the characters +, =, ;, & and #, to ensure they're not misinterpreted. The = symbol is a little interesting since technically it only needs escaping in keys; when encoding a value, the = character has already come before it, so doesn't need escaping again.