Cannot load a NSURL with spaces or hashtags in iPhone app
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(@"%@%开发者_StackOverflow@",@"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.
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.
Try this:
NSString* urlText = @"http://www.twitter.com/home?status=@HelloWorld Hello World";
NSString* newText = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,(CFStringRef)urlText,NULL,(CFStringRef)@"!*'();:@&=+$,/?%#[]",kCFStringEncodingUTF8);
NSURL* url = [NSURL URLWithString: urlText];
if (![[UIApplication sharedApplication] openURL:(NSURL*)url])
NSLog(@"%@%@",@"Failed to open url:",[url description]);
I created this category on NSString for encoding strings as URLs:
@interface NSString (URLEncoding)
@property (readonly) NSString *URLEncodedString;
@end
@implementation NSString (URLEncoding)
- (NSString*)URLEncodedString
{
NSString *result = (NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)self, NULL, CFSTR("?=&+"), kCFStringEncodingUTF8);
return [result autorelease];
}
@end
In your case, you would use it like this:
NSString *urlText = @"http://www.twitter.com/home?status=@HelloWorld Hello World";
NSURL *url = [NSURL URLWithString:[urlText URLEncodedString]];
精彩评论