AFNetworking: encoding de cadenas de URL que contienen '%' – falla el símbolo

Estoy usando AFNetworking en mi aplicación iOS. Descubrí un problema que ocurre cuando los parameters de request contienen signos de porcentaje. Entonces falla la encoding. El método AFURLEncodedStringFromStringWithEncoding devuelve nil.

He probado este código y se imprime (null) :

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

El resultado esperado debería ser: %25 . Otros caracteres pueden codificarse sin problemas.

El método se define de la siguiente manera:

 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 unpnetworkingictable sequences that may already contain percent escapes. return [(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)[string stringByReplacingPercentEscapesUsingEncoding:encoding], NULL, (CFStringRef)kAFLegalCharactersToBeEscaped, CFStringConvertNSStringEncodingToEncoding(encoding)) autorelease]; } 

¿Alguna idea de qué va mal aquí?

EDITAR: el problema se solucionó en AFNetworking .

No sé acerca de la API, pero la encoding de URL normalmente se realiza mediante

  • UTF-8 que codifica las porciones de cadena – ruta, arguments, etc. – en bytes
  • aplicando porcentajes de encoding de los valores de bytes para get piezas de cadena ASCII solamente
  • ensamblando las piezas de URL junto con los separadores:, /,?, & etc.
  • codificar esa cadena en bytes nuevamente
  • enviándolo por el cable

Vea http://tools.ietf.org/html/rfc3986#section-2.5 para conocer los matices. Tenga en count que el RFC establece que si la URL se refiere a un documento en un sistema EBCDIC, la URL debe especificar los valores de byte para la encoding EBCDIC de su nombre, no el nombre de cadena que conocen los usuarios humanos del sistema EBCDIC. Entonces, una URL es en última instancia un byte-string, no una cadena de caracteres.

En cuanto a cómo hacer que su API represente ese byte-string correctamente, no estoy seguro.

Simplemente eliminando el stringByReplacingPercentEscapesUsingEncoding:encoding está bien, no es necesario codificar dos veces, por lo que el valor de retorno debería ser:

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