Cannot load a NSURL with spaces or hashtags in iPhone app

Alex picture Alex · Apr 6, 2011 · Viewed 10.8k times · Source

Twitter has a nice feature that allows you to preload status messages using the following format:

http://twitter.com/?status=@HelloWorld Hello World

or alternatively:

http://twitter.com/?status=%40HelloWorld%20Hello%20World

I am trying to add a button to my iPhone app which will open Safari to the above pre-populated tweet.

However I am running into the problem where the percentage signs are being double escaped.

Here is the code that I have tried:

First an example of what does work

NSString* urlText = @"http://www.twitter.com/home?status=@HelloWorld";
NSURL *url = [NSURL URLWithString: urlText];
if (![[UIApplication sharedApplication] openURL:(NSURL*)url])
        NSLog(@"%@%@",@"Failed to open url:",[url description]);

This code works like a charm and outputs:

http://twitter.com/?status=%40HelloWorld

Code that doesn't work

NSString* urlText = @"http://www.twitter.com/home?status=@HelloWorld Hello World";
NSURL *url = [NSURL URLWithString: urlText];
if (![[UIApplication sharedApplication] openURL:(NSURL*)url])
        NSLog(@"%@%@",@"Failed to open url:",[url description]);

This creates a null NSURL. This I can only assume because URLWithString does not accept text with spaces in it.

So I tried this code:

NSString* urlText = @"http://www.twitter.com/home?status=@HelloWorld%20Hello%20World";
NSURL *url = [NSURL URLWithString: urlText];
if (![[UIApplication sharedApplication] openURL:(NSURL*)url])
   NSLog(@"%@%@",@"Failed to open url:",[url description]);

However that creates the URL:

http://twitter.com/?status=%40HelloWorld%2520Hello%2520World

So I have escaped my percentage sign %, which is of course not what I intended.

Of course people have been talking about using the function: stringByAddingPercentEscapesUsingEncoding

So I wrote this code:

NSString* urlText = @"http://www.twitter.com/home?status=@HelloWorld%20Hello%20World";
urlText = [urlText stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

NSURL *url = [NSURL URLWithString: urlText];
if (![[UIApplication sharedApplication] openURL:(NSURL*)url])
    NSLog(@"%@%@",@"Failed to open url:",[url description]);

However you again get the double escaping problem:

http://twitter.com/?status=%40HelloWorld%2520Hello%2520World

I'm hoping that someone might know some sort of work around. Ideally I would like to also include hashtags, but for now just getting spaces in would be a huge step forward.

Answer

Alex picture Alex · Apr 7, 2011

So it turns out that the problem wasn't being caused by the NSURL object but twitter itself.

This is the correct code to use:

NSString* urlText = @"http://twitter.com/home?status=@HelloWorld Hello World";
urlText = [urlText stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

NSURL *url = [NSURL URLWithString: urlText];
if (![[UIApplication sharedApplication] openURL:(NSURL*)url])
    NSLog(@"%@%@",@"Failed to open url:",[url description]);

One thing I didn't realize about twitter is this using this twitter address:

http://www.twitter.com/home?status=

will auto-escape your status.

While:

http://twitter.com/home?status=

will not auto-escape.