Невозможно загрузить NSURL с пробелами или хэштегами в приложении iPhone.

Twitter имеет приятную функцию, которая позволяет предварительно загружать сообщения о состоянии в следующем формате:

http://twitter.com/[email protected] Hello World

или, альтернативно:

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

Я пытаюсь добавить кнопку в мое приложение для iPhone, которое откроет Safari для вышеуказанного предварительно заполненного твита.

Однако я столкнулся с проблемой, когда процентные знаки удваиваются.

Вот код, который я пробовал:

Сначала пример того, что работает

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

Этот код работает как шарм и выдает:

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

Код, который не работает

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

Это создает нулевой NSURL. Это я могу только предположить, потому что URLWithString не принимает текст с пробелами в нем.

Итак, я пробовал этот код:

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

Однако это создает URL-адрес:

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

Итак, я избежал своего процентного знака%, что, конечно, не то, что я намеревался.

Конечно, люди говорили об использовании функции: stringByAddingPercentEscapesUsingEncoding

Итак, я написал этот код:

NSString* urlText = @"http://www.twitter.com/[email protected]%20Hello%20World";
urlText = [urlText stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

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

Однако вы снова получите проблему с двойным экранированием:

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

Я надеюсь, что кто-то может знать какую-то работу. В идеале я хотел бы также включить хэштеги, но пока просто пробелы в них станут огромным шагом вперед.

Ответы

Ответ 1

Итак, оказывается, что проблема не была вызвана объектом NSURL, а сама твиттер.

Это правильный код для использования:

NSString* urlText = @"http://twitter.com/[email protected] Hello World";
urlText = [urlText stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

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

Одна вещь, о которой я не знал о твиттере, - это использование этого твиттер-адреса:

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

автоматически удалит ваш статус.

В то время как:

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

не будет автоматически удаляться.

Ответ 2

Попробуйте следующее:

    NSString* urlText = @"http://www.twitter.com/[email protected] 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]);

Ответ 3

Я создал эту категорию в NSString для кодирования строк в виде URL-адресов:

@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

В вашем случае вы будете использовать его следующим образом:

NSString *urlText = @"http://www.twitter.com/[email protected] Hello World";
NSURL *url = [NSURL URLWithString:[urlText URLEncodedString]];