AFNetworking: кодирование строк URL, содержащих '%' - знак не выполняется - PullRequest
4 голосов
/ 25 января 2012

Я использую AFNetworking в моем приложении для iOS.Я обнаружил проблему, которая возникает, когда параметры запроса содержат знаки процента.Тогда кодирование не выполняется.Метод AFURLEncodedStringFromStringWithEncoding возвращает ноль.

Я тестировал этот код, и он печатает (null):

NSLog(@"%@", AFURLEncodedStringFromStringWithEncoding(@"%", NSUTF8StringEncoding));

Ожидаемый результат должен быть: %25.Другие символы могут быть закодированы без проблем.

Метод определяется следующим образом:

NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSStringEncoding encoding) {
    static NSString * const kAFLegalCharactersToBeEscaped = @"?!@#$^&%*+,:;='\"`<>()[]{}/\\|~ ";

    // Following the suggestion in documentation for `CFURLCreateStringByAddingPercentEscapes` to "pre-process" URL strings (using stringByReplacingPercentEscapesUsingEncoding) with unpredictable sequences that may already contain percent escapes.
    return [(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)[string stringByReplacingPercentEscapesUsingEncoding:encoding], NULL, (CFStringRef)kAFLegalCharactersToBeEscaped, CFStringConvertNSStringEncodingToEncoding(encoding)) autorelease];
}

Есть идеи, что здесь происходит не так?

РЕДАКТИРОВАТЬ: Эта проблема была исправлена ​​в AFNetworking .

Ответы [ 2 ]

1 голос
/ 25 января 2012

Я не знаю об API, но кодирование URL обычно выполняется

  • UTF-8, кодирующий части строки - путь, аргументы и т. Д. - в байтах
  • применение процентного кодирования байтовых значений для получения кусочков только для ASCII
  • сборка частей URL вместе с разделителями:, /,?, И т. Д.
  • кодирование этой строки в байты снова
  • отправка по проводам

См. http://tools.ietf.org/html/rfc3986#section-2.5 для нюансов. Обратите внимание, что в RFC говорится, что если URL ссылается на документ в системе EBCDIC, URL должен указывать байтовые значения для кодировки его имени EBCDIC, а не имя строки, по которой его знают пользователи системы EBCDIC. Таким образом, URL в конечном итоге является строкой байтов, а не символьной строкой.

Что касается того, как заставить ваш API правильно представлять эту байтовую строку, я не уверен.

0 голосов
/ 16 марта 2012

Просто удалить stringByReplacingPercentEscapesUsingEncoding:encoding нормально, нет необходимости дважды кодировать, поэтому возвращаемое значение должно быть:

return [(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, 
                    (CFStringRef)string, 
                    NULL, 
                    (CFStringRef)kAFLegalCharactersToBeEscaped, 
                    CFStringConvertNSStringEncodingToEncoding(encoding)) autorelease];
...