Escaping URL queries in Cocoa

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.

© Mike Abdullah 2007-2015