2010-04-07 12 views
12

Estoy tratando de codificar una cadena URL para formar una solicitud GET desde Object-C.URLEcodificando una cadena con Objective-C

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

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

Ésta es la categoría que se extiende NSString

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

Así que la primera vez que lo ejecuto me da vuelta

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

desde el cuadro de diálogo.

Inmediatamente después de ejecutar de nuevo me sale este

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

Entonces, si me haces otra vez se remonta a la primera. Es realmente extraño.

Si params está establecido en @ "&" o @ "" Acabo de obtener un "2" (sin las comillas) en el cuadro de diálogo.

¿Hay alguna forma en que pueda mostrar los signos% en el cuadro de diálogo de alerta?

Gracias

+1

¿por qué llama él dos veces y por qué no estás registrando tu salida en lugar de meterla en una alerta? –

Respuesta

23

creo que el NSAlert es la interpretación de los personajes % como especificadores de formato de cadena que están siendo llenados con datos aleatorios. Sólo NSLog la salida y que está bien:

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

Además, usted tiene una pérdida de memoria en su método -urlEncoded categoría. Usted crea la cadena usando una función CF que contiene Create, por lo que es responsable de liberarla.

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

Gracias por la advertencia de pérdida de memoria. En realidad, el problema persiste con NSLog también. Lo arreglé reemplazando% con %% en la cadena detallada en mi respuesta a continuación. – Chris

+3

Eso significa que probablemente estés usando 'NSLog' de esta manera:' NSLog (codificado) '. El primer argumento para 'NSLog' es una cadena de formato, no una cadena simple. Cualquier marcador de posición de formato de cadena será reemplazado por los argumentos que siguen, que en ese caso no están definidos. Debe registrar la cadena de esta manera: 'NSLog (@"% @ ", codificado);'. –

+1

Usando 'return [NSMakeCollectable (urlString) autorelease];' también lo hace GC-clean, y evita el lanzamiento. –

1

OK resulta que no fue un problema. Estaba siendo codificado correctamente porque revisé los registros del servidor y parece que los parámetros de solicitud fueron codificados.

Y para mostrar la cadena codificada en el cuadro de diálogo correctamente, acabo de reemplazar todas las instancias de% con %% después del hecho.

6

He abierto mi clase de utilidad del codificador URL que omite de forma inteligente el dominio y la parte de la ruta de la URL (para evitar la codificación de las barras, etc ...) y escapa solo las secuencias porcentuales que no son seguidas por 2- dígitos de códigos hexadecimales (para evitar la doble codificación de porcentajes como este:% 20 ->% 2520).

Se ha probado contra más de 10.000 URL y es muy robusto y eficiente.

Puede obtener más información sobre (y descargar) mi implementación aquí ... http://jayfuerstenberg.com/devblog/url-encoding-in-objective-c

2

En lugar de disparador automático, que ya no está disponible cuando se usa ARC, crear su método de instancia al pasar una cadena y usar CFBridgingRelease:

- (NSString *)urlEncodeWithString: (NSString*)string 
{ 
    CFStringRef urlString = CFURLCreateStringByAddingPercentEscapes(
                    NULL, 
                    (CFStringRef)string, 
                    NULL, 
                    (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ", 
                    kCFStringEncodingUTF8); 
    return (NSString *)CFBridgingRelease(urlString); 
} 
0

En mi opinión la forma más fácil es usar método conveniente suministrado con NSString (NSURLUtilities) categoría

Mi aplicación:

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

No funciona. Traduce "Esta es mi declaración +. ¿Entendido?" a "This + is + my +++ statement. + Got + it?" en lugar de "This + is + my +% 2B + statement. + Got + it% 3F". – Volomike

Cuestiones relacionadas