Domanda

In un'applicazione che sto scrivendo ho del codice come questo:

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

NSURL* url = [NSURL URLWithString:myurl];

[ws openURL:url];

La differenza principale è questa miourl viene da qualche parte fuori dal mio controllo.Nota %d nell'URL che non è del tutto corretto e significa che URLWithString fallisce, restituendo zero.

Qual è il modo "corretto" di gestire questa situazione?Devo analizzare la stringa e codificare correttamente gli argomenti?Oppure c'è qualche metodo intelligente in Cocoa che fa tutto il duro lavoro per me?

È stato utile?

Soluzione

Non sono sicuro che questo sia esattamente quello che stai cercando, ma esiste un metodo in NSString che sanitizzerà un URL:

stringByAddingPercentEscapesUsingEncoding:

Altri suggerimenti

Penso che il comportamento qui sia corretto, perché %d non è un componente valido di un URL (% è l'escape, ma si aspetta che lo seguano due caratteri esadecimali).

Non puoi semplicemente codificare tramite URL l'URL che ti è stato dato, perché ciò codificherebbe anche /s e ?s, cosa che non desideri.

Quindi la domanda è: qual è il comportamento corretto in questo caso?

Forse vorresti che fosse trasformato in...

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

(cioè.il % è codificato nella versione codificata di % in un URL, quindi quando il metodo riceve l'input, vede a come impostato su %d)

Non penso che esista alcuna funzione di libreria che possa fare questo genere di cose per te, dal momento che non esiste un modo "corretto" per farlo.L'unica cosa corretta che puoi fare è restituire un messaggio di errore che dice che l'URL che ti è stato fornito non è valido (proprio come lo è URLWithString)


Se volessi provare a gestire l'input, immagino che dovresti cercare nell'URL qualsiasi simbolo % che non sia immediatamente seguito da due caratteri esadecimali, quindi sostituire % con %25 in quel caso.Ciò dovrebbe essere del tutto possibile con un'espressione regolare, anche se sospetto che potrebbero esserci alcune complessità aggiuntive se i tuoi URL iniziano a contenere versioni codificate di caratteri al di fuori del set di caratteri ASCII.

Purtroppo bisogna essere più intelligenti di quanto previsto da Apple:

stringByAddingPercentEscapesUsingEncoding:

Questo eviterà tutti i caratteri URL non validi in modo che "http://foo.com/hey%20dude/", che è valido, diventi "http://foo.com/hey%2520dud/", che non è ciò che vogliamo .

Secondo la documentazione di Apple: http://developer.apple.com/library/mac/documentation/CoreFOundation/Reference/CFURLRef/Reference/reference.html#//apple_ref/c/func/CFURLCreateStringByAddingPercentEscapes

Ho creato una categoria NSURL che fa la cosa giusta e funziona con stringhe strane come quelle con codifica parziale (ad esempio"http://foo.com/hey amico/i%20do%20it/").

Ecco il codice:

@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

Funziona bene con stringhe codificate UTF8 e ASCII.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top