URLEncoding строки с Objective-C - PullRequest
       15

URLEncoding строки с Objective-C

12 голосов
/ 07 апреля 2010

Я пытаюсь URL кодировать строку, чтобы сформировать запрос GET из target-c.

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

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

Это категория, расширяющая NSString

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

Итак, при первом запуске я получаю обратно

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

из диалогового окна.

Сразу после повторного запуска я получаю это

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

Тогда, если я снова запускаю его, он возвращается к первому. Это действительно странно.

Если для params установлено значение @ "&" или @ "", я просто получаю "2" (без кавычек) в диалоговом окне.

Также есть ли способ, чтобы знаки% отображались в диалоговом окне предупреждения?

Спасибо

Ответы [ 5 ]

23 голосов
/ 07 апреля 2010

Я думаю, NSAlert интерпретирует символы % как спецификаторы формата строки, которые заполняются случайными данными. Просто NSLog вывод и все нормально:

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

Кроме того, у вас утечка памяти в методе категории -urlEncoded. Вы создаете строку, используя функцию CF, содержащую Create, поэтому вы несете ответственность за ее освобождение.

-(NSString *) urlEncoded
{
   CFStringRef urlString = CFURLCreateStringByAddingPercentEscapes(
                                                   NULL,
                                                   (CFStringRef)self,
                                                   NULL,
                                                   (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
                                                   kCFStringEncodingUTF8 );
    return [(NSString *)urlString autorelease];
}
6 голосов
/ 09 января 2012

Я открыл исходный код своего служебного класса кодировщика URL-адресов, который интеллектуально пропускает часть URL-адреса домена и пути (чтобы избежать кодирования косой черты и т. Д.) И экранирует только последовательности процентов, за которыми не следует 2-значный шестнадцатеричные коды (чтобы предотвратить двойное кодирование процентов, например:% 20 ->% 2520).

Он был протестирован для более чем 10000 URL-адресов, очень надежен и эффективен.

Вы можете узнать больше (и скачать) мою реализацию здесь ... http://jayfuerstenberg.com/devblog/url-encoding-in-objective-c

2 голосов
/ 06 августа 2013

Вместо автоматического выпуска, который больше не доступен при использовании ARC, создайте метод экземпляра, передав строку и используя CFBridgingRelease:

- (NSString *)urlEncodeWithString: (NSString*)string
{
  CFStringRef urlString = CFURLCreateStringByAddingPercentEscapes(
                                                                  NULL,
                                                                  (CFStringRef)string,
                                                                  NULL,
                                                                  (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
                                                                  kCFStringEncodingUTF8 );
  return (NSString *)CFBridgingRelease(urlString);
}
1 голос
/ 07 апреля 2010

ОК, оказалось, что это был не выпуск.Он был закодирован правильно, потому что я проверил журналы сервера, и кажется, что параметры запроса были закодированы.

И для правильного отображения закодированной строки в диалоговом окне я просто заменил все экземпляры% на %% послефакт.

0 голосов
/ 11 апреля 2014

На мой взгляд, самый простой способ - использовать удобный метод, поставляемый с NSString (NSURLUtilities) категория

Моя реализация:

- (NSString *) urlEncodedString
{
    NSString *result = [self stringByReplacingOccurrencesOfString:@" " withString:@"+"];
    result = [result stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    return result;
}
...