views:

724

answers:

2

I'm trying to URL encode a string to form a GET request from objective-c.

NSString *params = @"'Decoded data!'/foo.bar:baz";

NSRunAlertPanel( @"Error", [params urlEncoded], @"OK", nil, nil );

This is the category extending NSString

    -(NSString *) urlEncoded
{
    NSString *encoded = (NSString *)CFURLCreateStringByAddingPercentEscapes(
                                                   NULL,
                                                   (CFStringRef)self,
                                                   NULL,
                                                   (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
                                                   kCFStringEncodingUTF8 );
    return encoded;
}

So the first time I run it I get back

1606410046ecoded          1606410784ata2270.000000foo.bar0X1.001716P-1042baz

from the dialog box.

Immediately after I run it again I get this

1606410046ecoded          1606410944ata227369374562920703448982951250259562309742470533728899744288431318481119278377104028261651081181287077973859930826299575521579020410425419424562236383226511593137467590082636817579938932512039895040.000000foo.bar0X1.66E6156303225P+771baz

Then if I run it AGAIN it goes back to the first one. It's really weird.

If params is set to @"&" or @" " I just get back a "2" (w/o the quotes) in the dialog box.

Also is there a way I can have the % signs be shown in the alert dialog?

Thanks

+4  A: 

I think the NSAlert is interpreting the % characters as string format specifiers which are being filled with random data. Just NSLog the output and it's fine:

%27Decoded%20data%21%27%2Ffoo.bar%3Abaz

Also, you have a memory leak in your -urlEncoded category method. You create the string using a CF function containing Create so you are responsible for releasing it.

-(NSString *) urlEncoded
{
   CFStringRef urlString = CFURLCreateStringByAddingPercentEscapes(
                                                   NULL,
                                                   (CFStringRef)self,
                                                   NULL,
                                                   (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
                                                   kCFStringEncodingUTF8 );
    return [(NSString *)urlString autorelease];
}
Rob Keniger
Thanks for the memory leak warning. Actually the problem persists with NSLog too. I fixed it by replacing % with %% in the string detailed in my response below.
Chris
That means you're probably using `NSLog` like this: `NSLog(encoded)`. The first argument to `NSLog` is a format string, not a plain string. Any string format placeholders will be replaced with the arguments which follow, which in that case are undefined. You must log the string like this: `NSLog(@"%@",encoded);`.
Rob Keniger
A: 

OK turns out it was a nonissue. It was being encoded correctly because I checked the server logs and it seems the request params were encoded.

And for displaying the encoded string in the dialog box correctly, I just replaced all instances of % with %% after the fact.

Chris