2010-04-07 12 views
12

Sto provando a codificare URL una stringa per formare una richiesta GET dall'obiettivo-c.URLEncoding di una stringa con Objective-C

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

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

Questa è la categoria che si estende NSString

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

Così la prima volta l'eseguo mi tornare

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

dalla finestra di dialogo.

Subito dopo corro di nuovo ho questa

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

Poi se l'eseguo di nuovo risale al primo. È davvero strano

Se params è impostato su @ "&" o @ "" Ho appena ottenuto un "2" (senza le virgolette) nella finestra di dialogo.

C'è anche un modo per visualizzare i segni% nella finestra di avviso?

Grazie

+1

Perché stai chiamando due volte e perché non stai registrando il tuo output invece di inserirlo in un avviso? –

risposta

23

penso che il NSAlert è interpretare i % personaggi come identificatori di formato stringa che vengono riempite con dati casuali. Basta NSLog l'output e va bene:

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

Inoltre, si dispone di una perdita di memoria nel metodo -urlEncoded categoria. La stringa viene creata utilizzando una funzione CF contenente Create in modo da essere responsabile del rilascio.

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

Grazie per l'avviso di perdita di memoria. In realtà il problema persiste anche con NSLog. L'ho risolto sostituendo% con %% nella stringa descritta nella mia risposta di seguito. – Chris

+3

Ciò significa che probabilmente stai utilizzando 'NSLog' come questo:' NSLog (encoded) '. Il primo argomento di 'NSLog' è una stringa di formato, non una stringa semplice. Qualsiasi segnaposto di formato stringa verrà sostituito con gli argomenti che seguono, che in quel caso non sono definiti. È necessario registrare la stringa in questo modo: 'NSLog (@"% @ ", encoded);'. –

+1

Usando 'return [NSMakeCollectable (urlString) autorelease];' lo rende anche GC-clean, ed evita il cast. –

1

OK risulta che non era un problema. È stato codificato correttamente perché ho controllato i log del server e sembra che i parametri della richiesta siano stati codificati.

E per visualizzare correttamente la stringa codificata nella finestra di dialogo, ho appena sostituito tutte le istanze di% con %% dopo il fatto.

6

Ho aperto la mia classe di utilità codificatore URL che ignora in modo intelligente il dominio e la porzione di percorso dell'URL (per evitare di codificare le barre, ecc ...) ed evita solo le sequenze percentuali non seguite da 2 cifra codici esadecimali (per evitare la doppia codifica di percentuali come questa:% 20 ->% 2520).

È stato testato su oltre 10.000 URL ed è molto robusto e performante.

Puoi saperne di più su (e scaricare) la mia implementazione qui ... http://jayfuerstenberg.com/devblog/url-encoding-in-objective-c

2

Piuttosto che autorelease, che non è più disponibile quando si utilizza ARC, crea il tuo metodo di istanza passando una stringa e l'utilizzo di CFBridgingRelease:

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

A mio parere il modo più semplice è quello di utilizzare metodo conveniente in dotazione con NSString (NSURLUtilities) categoria

mia realizzazione:

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

Non funziona. Traduce "Questa è la mia + affermazione. Capito?" a "Questa + è + mia istruzione ++ ++. + Hai +?" invece di "Questo + è + mio +% 2B + istruzione. + Hai + it% 3F". – Volomike

Problemi correlati