2009-05-27 10 views
8

Estoy intentando enviar el contenido de UITextView o UITextField como parámetros a un archivo PHPespacios de codificación en UITextView/UITextField a formato de URL

NSString *urlstr = [[NSString alloc] initWithFormat:@"http://server.com/file.php?name=%@&tags=%@&entry=%@",nameField.text, tagsField.text, dreamEntry.text]; 

Cuando i urlStr registro, el formato de URL es aceptable con tal de como UITextView o UITextField no contienen espacios. ¿Cómo voy a convertir los espacios a% 20?

edición

Este es el código en la actualidad, que no sólo se bloquea, pero no es la codificación de la URL correctamente.

name = John Doe & tags = pesadilla recurrente & entrada = Pruebas Pruebas Pruebas

se convierte en

name = John -1844684964oe & tags = recurringightmare & entrada = Prueba -1.992836e 4.214929e-307sting + 00sting

- (IBAction)sendButtonPressed:(id)sender 
{ 

    NSString *urlString = [[NSString alloc] initWithFormat:@"http://server.com/file.php?name=%@&tags=%@&entry=%@", nameField.text, tagsField.text, dreamEntry.text]; 

    NSString *encodedString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 

    NSURL *url = [[NSURL alloc] initWithString:encodedString]; 

    NSLog(encodedString); 

    NSLog(urlString); 

    [urlString release]; 
    [url release]; 
    [encodedString release]; 


} 

Respuesta

14

Se supone que no debe escapar de la URL de la cadena completa, se supone que debe escapar de la URL de los componentes dinámicos. Trate

NSString *urlStr = [NSString stringWithFormat:@"http://server.com/file.php?name=%@&tags=%@&entry=%@", 
         [nameField.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], 
         [tagsField.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], 
         [dreamEntry.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], 
         nil]; 
NSURL *url = [NSURL URLWithString:urlStr]; 

El segundo problema con el código (y, sin duda, la razón de la impresión impar) es lo que está pasando la cadena directamente a NSLog, por lo que está siendo tratado como una cadena de formato. Debe utilizar

NSLog(@"%@", encodedString); 

en su lugar. Eso lo hará imprimir como se esperaba.

Editar: Un tercer problema con su código es que está mezclando objetos propios y liberados, y luego soltándolos al final. Ve a los 3 objetos que creas, y que posteriormente publicas más tarde. Uno de ellos no debería publicarse más tarde porque fue producido por un método que no comenzó con las palabras alloc, copy o new. Identificar el objeto en cuestión es un ejercicio dejado al lector.

+0

jeje punto tomado. ¡Gracias! – bcsantos

0

puede llevar a su URL y su uso:

NSString *urlStr = [[NSString alloc] initWithFormat:@"http://server.com/file.php?name=%@&tags=%@&entry=%@",nameField.text, tagsField.text, dreamEntry.text]; 

NSString *encStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 
+0

gracias por el puntero :) – bcsantos

+0

NP ... la respuesta anterior es de hecho más correcta. Thx ... –

20

En realidad, todas las respuestas anteriores contienen al menos algunas imprecisiones, que para muchos valores comunes de usuario proporcionada texto en los campos de texto no comunicarse correctamente con el servidor

stringByAddingPercentEscapesUsingEncoding: ciento escapa todos los caracteres que no son URL válida caracteres. Este método debería aplicarse una vez a la URL completa.

Una respuesta anterior afirma que stringByAddingPercentEscapesUsingEncoding: funciona como las clases de construcción de URL en muchos lenguajes de scripting, donde no debe aplicarlo a la cadena de URL completa, pero no es así. Cualquiera puede verificar esto fácilmente verificando su salida para & s sin protección y ? s. Por lo tanto, está bien aplicarlo a toda la cadena, pero no es suficiente para aplicarlo a su contenido de URL 'dinámico'.

La respuesta anterior es correcta en cuanto a que debe trabajar un poco más con los nombres y valores que entran en su cadena de consulta CGI. Como CGI está especificado por RFC3875, esto se conoce como porcentaje de escape de RFC3875.Se asegura de que sus nombres y valores no contienen caracteres que no son caracteres de URL válidos, pero que son importantes en otras partes de la URL (;, ?, :, @, &, =, $, +, {, }, < , > y ,)

Sin embargo, es muy importante terminar también haciendo escapes simples de porcentaje de URL en la cadena completa para asegurarse de que todos los caracteres de la cadena sean caracteres URL válidos. Si bien no lo hace en su ejemplo, en general podría haber caracteres en una parte "estática" de la cadena que no son caracteres de URL válidos, por lo que también debe escapar de ellos.

Desafortunadamente, NSString no nos da el poder de escapar de los caracteres significativos RFC3875, así que tenemos que sumergirnos en CFString para hacerlo. Obviamente usando CFString es un dolor por lo que generalmente agrego un Category en NSString así:

@interface NSString (RFC3875) 
- (NSString *)stringByAddingRFC3875PercentEscapesUsingEncoding:(NSStringEncoding)encoding; 
@end 

@implementation NSString (RFC3875) 
- (NSString *)stringByAddingRFC3875PercentEscapesUsingEncoding:(NSStringEncoding)encoding { 
    CFStringEncoding cfEncoding = CFStringConvertNSStringEncodingToEncoding(encoding); 
    NSString *rfcEscaped = (NSString *)CFURLCreateStringByAddingPercentEscapes(
               NULL, 
               (CFStringRef)self, 
               NULL, 
               (CFStringRef)@";/?:@&=$+{}<>,", 
               cfEncoding); 
    return [rfcEscaped autorelease]; 
} 
@end 

Con esta Category en su lugar, el problema original podría ser resuelto correctamente con los siguientes:

NSString *urlEscapedBase = [@"http://server.com/file.php" stringByAddingPercentEscapesUsingEncoding: 
              NSUTF8StringEncoding]; 
NSString *rfcEscapedName = [nameField.text stringByAddingRFC3875PercentEscapesUsingEncoding: 
               NSUTF8StringEncoding]; 
NSString *rfcEscapedTags = [tagsField.text stringByAddingRFC3875PercentEscapesUsingEncoding: 
               NSUTF8StringEncoding]; 
NSString *rfcEscapedEntry = [dreamEntry.text stringByAddingRFC3875PercentEscapesUsingEncoding: 
               NSUTF8StringEncoding]; 

NSString *urlStr = [NSString stringWithFormat:@"%@?name=%@&tags=%@&entry=%@", 
           urlEscapedBase, 
           rfcEscapedName, 
           rfcEscapedTags, 
           rfcEscapedEntry]; 

NSURL *url = [NSURL URLWithString:urlStr]; 

Esto se un poco variable pesado solo sea más claro. También tenga en cuenta que la lista de variables proporcionada a stringWithFormat: no debe ser nil terminada. La cadena de formato describe la cantidad precisa de variables que deberían seguirla. Además, técnicamente las cadenas para los nombres de cadena de consulta (nombre, etiquetas, entrada, ...) se deben ejecutar a través de stringByAddingPercentEscapesUsingEncoding: como una cuestión de rutina, pero en este pequeño ejemplo podemos ver fácilmente que no contienen caracteres de URL no válidos.

Para ver por qué las soluciones anteriores son incorrectas, imagine que el texto de entrada del usuario en dreamEntry.text contiene un &, que no es poco probable. Con las soluciones anteriores, todo el texto que sigue a ese carácter se perderá en el momento en que el servidor recibió ese texto, ya que el símbolo comercial sin escinde sería interpretado por el servidor como el final de la porción del valor de ese par de cadenas de consulta.

+1

felicitaciones. La respuesta actualmente "correcta" es como todos podemos ver un poco demasiado incorrecta. * sin embargo * al usar esto para escapar de los valores de los parámetros que se envían a la aplicación de Twitter, los resultados son confusos (en realidad solo un montón de% de caracteres). Si esto es un problema con la decodificación en nombre del cliente de Twitter o no, no lo sé. Sin embargo, funciona con otra solución que usa CFURLCreateStringByAddingPercentEscapes(). Obtuve esa solución desde aquí: http://wiki.akosma.com/IPhone_URL_Schemes#Note_about_URL_Encoding_in_Objective-C – Jonny

+0

La implementación de la Categoría que proporcioné es virtualmente idéntica a la solución a la que se vincula (también usa CFURLCreateStringByAddingPercentEscapes() para el pesado elevación, la principal diferencia es que la solución no está bien definida). Si tuvo un problema con la Categoría anterior, sospecho que estaba aplicando tanto stringByAddingRFC3875PercentEscapesUsingEncoding() como la cadena NSString normalByAddingPercentEscapesUsingEncoding() a la misma cadena, lo cual es malo, ya que el URL escape no es idempotente, por lo que comienza a escapar de los escapes (por ejemplo,% 20 se convierte en% 2520). – barrycburton

+0

En realidad, esta solución es * casi * correcta. A saber, la llamada a [self stringByAddingPercentEscapesUsingEncoding: encoding] es innecesaria, ya que CFURLCreateStringByAddingPercentEscapes() ya lo hará por usted.Entonces el método pasa a ser: - (NSString *) stringByAddingRFC3875PercentEscapesUsingEncoding: codificación (NSStringEncoding) { CFStringEncoding cfEncoding = CFStringConvertNSStringEncodingToEncoding (codificación); NSString * rfcEscaped = (NSString *) CFURLCreateStringByAddingPercentEscapes (NULL, (CFStringRef) self, NULL, (CFStringRef) @ "; /?: @ & = $ + {} <>,", CfEncoding); return [rfcEscaped autorelease]; } – lensovet

Cuestiones relacionadas