Proper URL (Percent) Encoding in iOS

iOS SDKIf you are developing an iPhone app makes RESTful remote calls to a server in the Internet, you will likely need to encode your parameter to a percent encoded string (aka URL-encoding) so that you can properly embed the information in a URI before passing it to the remote server. For example, say you have an address that looks like this:

One Broadway, Cambridge, MA

Under URL encoding, the string becomes:

One%20Broadway,%20Cambridge,%20MA

To encode a string using URL-encodng, simply use following method in NSString:

stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding

Conversely, you can use the following method to decode a URL-encoded string to back to its original text:

stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding

Full example:

NSString *rawText = @"One Broadway, Cambridge, MA";

NSString *encodedText = [rawText stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"Encoded text: %@", encodedText);
NSString *decodedText = [encodedText stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"Original text: %@", decodedText);

Here’s the output:
Encoded text: One%20Broadway,%20Cambridge,%20MA
Original text: One Broadway, Cambridge, MA

But there’s just one problem, stringByAddingPercentEscapesUsingEncoding doesn’t encode reserved characters like ampersand (&) and slash (/). For example:

NSString *rawText = @"Bed Bath & Beyond - URL=http://www.bedbathandbeyond.com/";

NSString *encodedText = [rawText stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"Encoded text: %@", encodedText);
NSString *decodedText = [encodedText stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"Original text: %@", decodedText);

Here’s the output:

Encoded text: Bed%20Bath%20&%20Beyond%20-%20URL=http://www.bedbathandbeyond.com/
Original text: Bed Bath & Beyond – URL=http://www.bedbathandbeyond.com/

As you can see, & and / (in bold red) aren’t encoded. As a workaround, use Foundation function CFURLCreateStringByAddingPercentEscapes instead (as suggested by Simon). Full example here:

// Encode a string to embed in an URL.
NSString* encodeToPercentEscapeString(NSString *string) {
  return (NSString *)
  CFURLCreateStringByAddingPercentEscapes(NULL,
                                          (CFStringRef) string,
                                          NULL,
                                          (CFStringRef) @"!*'();:@&=+$,/?%#[]",
                                          kCFStringEncodingUTF8);
}

// Decode a percent escape encoded string.
NSString* decodeFromPercentEscapeString(NSString *string) {
  return (NSString *)
  CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL,
                                                          (CFStringRef) string,
                                                          CFSTR(""),
                                                          kCFStringEncodingUTF8);
}

int main (int argc, const char * argv[]) {
  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

  NSString *rawText = @"Bed Bath & Beyond - URL=http://www.bedbathandbeyond.com/";

  NSString *encodedText = encodeToPercentEscapeString(rawText);
  NSLog(@"Encoded text: %@", encodedText);
  NSString *decodedText = decodeFromPercentEscapeString(encodedText);
  NSLog(@"Original text: %@", decodedText);

  [pool drain];
  return 0;
}

And the output:

Encoded text: Bed%20Bath%20%26%20Beyond%20-%20URL%3Dhttp%3A%2F%2Fwww.bedbathandbeyond.com%2F
Original text: Bed Bath & Beyond – URL=http://www.bedbathandbeyond.com/

This time it correct encode the & and / characters. Of course, you won’t be encoding the entire URL but only the URI parameters. There’s no code download for this, simply cut the above code snippets to your code and paste to your code base.

Errata (Feb 18, 2011)

CFURLCreateStringByAddingPercentEscapes returns a string reference with a retain count of +1. So remember to release it when you are done using it.

Code display and highlight plugin for WordPress

WordPress LogoI shopped around this weekend for a WordPress plugin that not only allows me to display code snippets on my blog but is also capable of syntax highlighting – thereby allowing the posted code to look pretty. For starters, this article provides a list of the top 12 WordPress code syntax display/highlight plugins. After installing and playing around with several plugins, I eventually settled for SyntaxHighlighter Evolved, which not only offers a great looking syntax highlighting theme against a dark background but is easily configurable and supports all of the programming languages I want to display on my blog, namely Objective-C, C#, Java, and JavaScript/HTML. Good stuff.