2010-04-07 11 views
12

Ich versuche URL codieren Sie eine Zeichenfolge, um eine GET-Anforderung von Objective-C zu bilden.URLEncoding eine Zeichenfolge mit Objective-C

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

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

Dies ist die Kategorie NSString erstreckt

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

Also das erste Mal, dass ich es betreibe ich

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

aus dem Dialogfeld zurück.

Unmittelbar nachdem ich es wieder laufen bekomme ich diese

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

Dann, wenn ich es laufen sie wieder zurück in die erste geht. Es ist wirklich komisch.

Wenn params auf @ "&" oder @ "" eingestellt ist, bekomme ich im Dialogfeld eine "2" (ohne Anführungszeichen) zurück.

Gibt es auch eine Möglichkeit, dass die% Zeichen im Alarmdialog angezeigt werden können?

Dank

+1

Warum rufst du es zweimal und warum protokollierst du deine Ausgabe nicht, anstatt sie in eine Warnung zu schieben? –

Antwort

23

Ich denke, die NSAlert die % Zeichen als String Formatbezeichner interpretiert, die mit Zufallsdaten gefüllt werden. Nur NSLog die Ausgabe und es ist in Ordnung:

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

Auch Sie ein Speicherleck in Ihrer -urlEncoded Kategorie Methode haben. Sie erstellen die Zeichenfolge mit einer CF-Funktion, die Create enthält, so dass Sie für die Freigabe verantwortlich sind.

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

Danke für die Speicherleckwarnung. Tatsächlich besteht das Problem weiterhin bei NSLog. Ich habe es behoben, indem ich% durch %% in der Zeichenfolge ersetzt habe, die in meiner Antwort unten aufgeführt ist. – Chris

+3

Das bedeutet, dass Sie 'NSLog' wahrscheinlich so verwenden: 'NSLog (encoded)'. Das erste Argument für 'NSLog' ist eine Formatzeichenfolge, keine einfache Zeichenfolge. Alle Platzhalter für Zeichenfolgenformate werden durch die folgenden Argumente ersetzt, die in diesem Fall nicht definiert sind. Sie müssen die Zeichenfolge wie folgt protokollieren: 'NSLog (@"% @ ", codiert);'. –

+1

Verwendung von 'return [NSMakeCollectable (urlString) Autorelease];' macht es auch GC-clean und vermeidet die Besetzung. –

1

OK stellt sich heraus, dass es ein Nonissue war. Es wurde korrekt codiert, weil ich die Serverprotokolle überprüft habe und es scheint, dass die Anfrageparameter verschlüsselt wurden.

Und um die codierte Zeichenfolge im Dialogfeld richtig anzuzeigen, habe ich gerade alle Instanzen von% mit %% nach der Tatsache ersetzt.

6

Ich habe meine URL-Encoder-Utility-Klasse geöffnet, die intelligent die Domain und den Pfadbereich der URL überspringt (um die Schrägstriche zu vermeiden usw.) und nur die Prozent-Sequenzen zu entgehen, die nicht von 2- gefolgt werden. Ziffern Hex-Codes (um eine doppelte Codierung von Prozenten wie diesem zu verhindern:% 20 ->% 2520).

Es wurde gegen mehr als 10.000 URLs getestet und ist sehr robust und performant.

Sie können hier mehr über meine Implementierung erfahren (und herunterladen) ... http://jayfuerstenberg.com/devblog/url-encoding-in-objective-c

2

Anstatt Autorelease, die nicht mehr verfügbar ist, wenn ARC verwenden, erstellen Sie Ihre Instanz-Methode durch einen String übergeben und mit CFBridgingRelease:

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

Meiner Meinung nach ist der einfachste Weg ist bequeme Methode geliefert zu verwenden mit NSString (NSURLUtilities) Kategorie

Meine Implementierung:

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

Funktioniert nicht. Übersetzt "Dies ist meine + Aussage. Verstanden?" zu "This + is + my +++ statement. + Got + it?" statt "Dies + ist + meine +% 2B + Aussage. + Erhielt es% 3F". – Volomike

Verwandte Themen