mike chambers | about

URL Encoding with Objective-C and Cocoa

Wednesday, October 31, 2007

I have been teaching myself Objective-C and Cocoa (in part so I can build native iPhone / iTouch apps), and have been working on a simple command line application named “turl”. This basically provides a command-line interface to url shortening services such as tinyurl.com and urltea.com.

Anyways, I ran into an issue where a specific URL was not being created correctly. It turns out, it was because I was not url encoding the url before sending it to the api. No problem I thought, I’ll just url encode it. However, after much searching, I found that Cocoa didn’t really provide a url encode API. I did find find a couple of possible solutions that used other APIs, but I could not get either one to work for me, and it didn’t appear that they were made specifically to URL encode urls.

So, I finally decided to make my own and figured I would post it here in case anyone else needs to use such an API.

//simple API that encodes reserved characters according to:
//RFC 3986
//http://tools.ietf.org/html/rfc3986
+(NSString *) urlencode: (NSString *) url
{
    NSArray *escapeChars = [NSArray arrayWithObjects:@";" , @"/" , @"?" , @":" ,
                                                        @"@" , @"&" , @"=" , @"+" ,
                                                        @"$" , @"," , @"[" , @"]",
                                                        @"#", @"!", @"'", @"(",
                                                        @")", @"*", nil];

    NSArray *replaceChars = [NSArray arrayWithObjects:@"%3B" , @"%2F" , @"%3F" ,
                                                        @"%3A" , @"%40" , @"%26" ,
                                                        @"%3D" , @"%2B" , @"%24" ,
                                                        @"%2C" , @"%5B" , @"%5D",
                                                        @"%23", @"%21", @"%27",
                                                        @"%28", @"%29", @"%2A", nil];

    int len = [escapeChars count];

    NSMutableString *temp = [url mutableCopy];

    int i;
    for(i = 0; i < len; i++)
    {

        [temp replaceOccurrencesOfString: [escapeChars objectAtIndex:i]
                                    withString:[replaceChars objectAtIndex:i]
                                    options:NSLiteralSearch
                                    range:NSMakeRange(0, [temp length])];
    }

    NSString *out = [NSString stringWithString: temp];

    return out;
}

Basically, it encode a string according to RFC 3986.

As I mentioned above, I am just learning Objective-C and Cocoa, so there may be a better way to do this, and the code above may need some tweaks. If you have any suggestions, please post them in the comments.

twitter github flickr behance