Pregunta

En una aplicación que estoy escribiendo tengo un código como este:

NSWorkspace* ws = [NSWorkspace sharedWorkspace];
NSString* myurl = @"http://www.somewebsite.com/method?a=%d";

NSURL* url = [NSURL URLWithString:myurl];

[ws openURL:url];

La principal diferencia es que miurl viene de algún lugar fuera de mi control.Tenga en cuenta el %d en la URL que no es del todo correcto y significa que URLWithString falla y devuelve nulo.

¿Cuál es la forma "correcta" de manejar esto?¿Necesito analizar la cadena y codificar correctamente los argumentos?¿O hay algún método inteligente en Cocoa que haga todo el trabajo duro por mí?

¿Fue útil?

Solución

No estoy seguro de si esto es exactamente lo que estás buscando, pero hay un método en NSString que desinfectará una URL:

stringByAddingPercentEscapesUsingEncoding:

Otros consejos

Creo que el comportamiento aquí es correcto, porque %d no es un componente válido de una URL (% es el escape, pero espera que lo sigan dos caracteres hexadecimales).

No puede simplemente codificar la URL tal como se le proporcionó, porque eso codificaría también los /s y ?s, lo cual no desea.

Entonces, la pregunta es, ¿cuál es el comportamiento correcto aquí?

Tal vez quieras que se convierta en...

http://www.somewebsite.com/method?a=%25d

(es decir.% está codificado en la versión codificada de % en una URL, por lo que cuando el método obtiene la entrada, ve que a está configurado en %d)

No creo que exista ninguna función de biblioteca que haga ese tipo de cosas por usted, ya que no existe una forma "correcta" de hacerlo.Lo único correcto que puedes hacer es devolver un mensaje de error que diga que la URL que te proporcionaron no es válida (al igual que URLWithString).


Si quisiera intentar manejar la entrada, supongo que necesitaría buscar en la URL cualquier símbolo % que no esté seguido inmediatamente por dos caracteres hexadecimales y luego reemplazar % con %25 en ese caso.Esto debería ser bastante posible con una expresión regular, aunque sospecho que puede haber algunas complejidades adicionales si sus URL comienzan a contener versiones codificadas de caracteres fuera del conjunto de caracteres ASCII.

Desafortunadamente, debes ser más inteligente que lo que proporciona Apple:

stringByAddingPercentEscapesUsingEncoding:

Esto escapará de todos los caracteres de URL no válidos para que "http://foo.com/hey%20dude/", que es válido, se convierta en "http://foo.com/hey%2520dud/", que no es lo que queremos. .

Según la documentación de Apple: http://developer.apple.com/library/mac/documentation/CoreFOundation/Reference/CFURLRef/Reference/reference.html#//apple_ref/c/func/CFURLCreateStringByAddingPercentEscapes

Creé una categoría NSURL que hace lo correcto y funciona con cadenas impares, como las que tienen codificación parcial (es decir,"http://foo.com/hey amigo/i%20do%20it/").

Aquí está el código:

@interface NSURL (SmartEncoding)
+ (NSURL *)smartURLWithString:(NSString *)str;
@end

@implementation NSURL (SmartEncoding)

+ (NSURL *)smartURLWithString:(NSString *)str
{
    CFStringRef preprocessed = CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (CFStringRef)str, CFSTR(""), kCFStringEncodingUTF8);
    if (!preprocessed) 
        preprocessed = CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (CFStringRef)str, CFSTR(""), kCFStringEncodingASCII);

    if (!preprocessed)
        return [NSURL URLWithString:str];

    CFStringRef sanitized = CFURLCreateStringByAddingPercentEscapes(NULL, preprocessed, NULL, NULL, kCFStringEncodingUTF8);
    CFRelease(preprocessed);
    NSURL *result = (NSURL*)CFURLCreateWithString(NULL, sanitized, NULL);
    CFRelease(sanitized);
    return [result autorelease];
}

@end

Funciona bien con cadenas codificadas en UTF8 y ASCII.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top