2009-05-27 10 views
8

Ich versuche, den Inhalt von UITextView oder UITextField als Parameter an eine PHP-DateiEncoding Räume in UITextView/UITextField zu URL-Format

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

zu senden Wenn ich urlStr einzuloggen, ist das URL-Format genauso ok lang da UITextView oder UITextField keine Leerzeichen enthalten. Wie würde ich die Leerzeichen in% 20 konvertieren?

bearbeiten

hier ist der Code zur Zeit, die nicht nur Abstürze, aber die URL nicht korrekt kodiert.

name = John Doe & tags = wiederkehrenden Alptraum & entry = Testing testing testing

zu

Namen umgewandelt wird = John -1844684964oe & tags = recurringightmare & Eintrag = Testing 4.214929e-307sting -1.992836e + 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]; 


} 

Antwort

14

Sie sollten nicht die gesamte Zeichenfolge URL-Escape, Sie sollen URL-Escape der dynamischen Komponenten. Versuchen

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]; 

Das zweite Problem mit Ihrem Code (und zweifellos der Grund für den ungeraden Druck) ist, dass Sie die Zeichenfolge direkt an NSLog vorbei sind, so dass es wird als Format-String behandelt. Sie müssen

NSLog(@"%@", encodedString); 

stattdessen verwenden. Dadurch wird es wie erwartet gedruckt.

Bearbeiten: Ein drittes Problem mit Ihrem Code ist, dass Sie automatisch freigegebene und im Besitz befindliche Objekte mischen und dann am Ende alle freigeben. Sehen Sie sich die 3 Objekte an, die Sie erstellen und die Sie später freigeben. Eine davon sollte nicht später veröffentlicht werden, da sie mit einer Methode erstellt wurde, die nicht mit den Wörtern alloc, copy oder new beginnt. Das Objekt zu identifizieren ist eine Übung, die dem Leser überlassen bleibt.

+0

hehe Punkt genommen. Vielen Dank! – bcsantos

0

Sie können Ihre URL und Nutzung nehmen:

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

danke für den Zeiger :) – bcsantos

+0

NP ... die obige Antwort ist in der Tat richtiger. Thx ... –

20

Eigentlich alle bisherigen Antworten enthalten zumindest einige Ungenauigkeiten, die für viele gemeinsame Werte anzeigen Text in den Textfeldern versehen wäre nicht richtig mit dem Server kommunizieren

stringByAddingPercentEscapesUsingEncoding: Prozent entkommt alle Zeichen, die nicht gültig URL sind Figuren. Diese Methode sollte einmal auf die gesamte URL angewendet werden.

Eine frühere Antwort behauptet, dass stringByAddingPercentEscapesUsingEncoding: funktioniert wie die URL-Erstellung Klassen in vielen Skriptsprachen, wo Sie es nicht auf die gesamte URL-Zeichenfolge anwenden sollten, aber es nicht. Jeder kann dies leicht überprüfen, indem er seine Ausgabe für unescaped & s und ? s überprüft. Es ist also in Ordnung, sie auf die gesamte Zeichenfolge anzuwenden, es reicht jedoch nicht aus, sie auf Ihren dynamischen URL-Inhalt anzuwenden.

Die vorherige Antwort ist richtig, dass Sie mehr Arbeit an den Namen und Werten, die in Ihre CGI-Abfrage-Zeichenfolge gehen müssen. Da CGI durch RFC3875 spezifiziert ist, wird dies oft als RFC3875 Prozent Escaping bezeichnet.Es stellt sicher, dass Ihre Namen und Werte keine Zeichen enthalten, die gültige URL Zeichen sind, die aber in anderen Teilen der URL von Bedeutung sind (;, ?, :, @, &, =, $, +, {, }, < (> und ,)

Es ist jedoch sehr wichtig, auch zu beenden, indem Sie URL-Prozent-Escapes für die vollständige Zeichenfolge ausführen, um sicherzustellen, dass alle Zeichen in der Zeichenfolge gültige URL-Zeichen sind. Während Sie in Ihrem Beispiel nicht sind, könnten im Allgemeinen Zeichen in einem 'statischen' Teil der Zeichenkette sein, die keine gültigen URL-Zeichen sind, also müssen Sie auch diese entschlüsseln.

Leider NSString gibt uns nicht die Möglichkeit, die RFC3875 signifikanten Zeichen zu entkommen, so müssen wir in CFString zu tun, um dies zu tun. Offensichtlich CFString Verwendung eines Schmerz so allgemein füge ich eine Category auf NSString wie so:

@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 

Mit diesem Category an Ort und Stelle, konnte das ursprüngliche Problem richtig mit der folgenden gelöst werden:

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]; 

Dies wird ein wenig variabel schwer ist nur klarer. Beachten Sie auch, dass die zu stringWithFormat: gelieferte Variablenliste nicht nil beendet sein sollte. Die Formatzeichenfolge beschreibt die genaue Anzahl der Variablen, die darauf folgen sollen. Auch technisch sollten die Strings für Query-String-Namen (Name, Tags, Entry, ..) selbstverständlich durch stringByAddingPercentEscapesUsingEncoding: laufen, aber in diesem kleinen Beispiel können wir leicht erkennen, dass sie keine ungültigen URL-Zeichen enthalten.

Um zu sehen, warum die vorherigen Lösungen falsch sind, stellen Sie sich vor, dass der Benutzereingabetext in dreamEntry.text einen & enthält, was nicht unwahrscheinlich ist. Bei den vorherigen Lösungen würde der gesamte Text, der diesem Zeichen folgt, zu dem Zeitpunkt verloren gehen, zu dem der Server diesen Text erhalten hat, da das nicht-skalierte Et-Zeichen vom Server als Ende des Wertteils dieses Abfrage-String-Paares interpretiert wird.

+1

Kudos. Die zur Zeit "richtige" Antwort ist, wie wir alle sehen können, ein bisschen zu falsch. * jedoch * Wenn diese Option verwendet wird, um Parameterwerte zu verwerfen, die an die Twitter-App gesendet werden, werden die Ergebnisse verzerrt (eigentlich nur ein paar% Zeichen). Wenn dies ein Problem mit der Entschlüsselung im Namen des Twitter-Kunden ist oder nicht, weiß ich nicht. Es funktioniert jedoch mit einer anderen Lösung, die CFURLCreateStringByAddingPercentEscapes() verwendet. Ich habe diese Lösung von hier: http://wiki.akosma.com/IPhone_URL_Schemes#Note_about_URL_Encoding_in_Objective-C – Jonny

+0

Die Implementierung der Kategorie, die ich zur Verfügung gestellt wurde, ist praktisch identisch mit der Lösung, die Sie verknüpfen (es verwendet auch CFURLCreateStringByAddingPercentEscapes() für die schweren Der Hauptunterschied ist, dass die Lösung nicht sauber verpackt ist). Wenn Sie ein Problem mit der obigen Kategorie hatten, vermute ich, dass Sie sowohl stringByAddingRFC3875PercentEscapesUsingEncoding() als auch den normalen NSString stringByAddingPercentEscapesUsingEncoding() auf die gleiche Zeichenfolge angewendet haben, was schlecht ist, da die URL-Escaping nicht idempotent ist. zB% 20 wird% 2520). – barrycburton

+0

Eigentlich ist diese Lösung * fast * korrekt. Der Aufruf von [self stringByAddingPercentEscapesUsingEncoding: encoding] ist nämlich nicht notwendig, da CFURLCreateStringByAddingPercentEscapes() das bereits für Sie erledigt.So wird die Methode: - (NSString *) stringByAddingRFC3875PercentEscapesUsingEncoding: (NSStringEncoding) Codierung { CFStringEncoding cfEncoding = CFStringConvertNSStringEncodingToEncoding (Codierung); NSString * rfcEscaped = (NSString *) CFURLCreateStringByAddingPercentEscapes (NULL, (CFStringRef) selbst, NULL, (CFStringRef) @ "; /?: @ & = $ + {} <>,", CfEncoding); Rückkehr [rfcEscaped Autorelease]; } – lensovet