2009-05-27 11 views
8

J'essaie d'envoyer le contenu de UITextView ou UITextField en tant que paramètres dans un fichier phpespaces de codage dans UITextView/UITextField au format URL

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

Quand je urlstr journal, le format d'URL est ok aussi longtemps comme UITextView ou UITextField ne contiennent pas d'espaces. Comment ferais-je pour convertir les espaces en% 20?

modifier

est le code ici à l'heure actuelle, qui non seulement se bloque mais n'est pas l'encodage URL correctement.

name = John Doe & tags = cauchemar récurrent & entrée = test d'essai d'essai

est converti en

name = John -1844684964oe & balises = recurringightmare entrée & = Test -1.992836e de 4.214929e-307sting + 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]; 


} 

Répondre

14

Vous n'êtes pas censé échapper l'URL de la chaîne entière, vous êtes censé échapper à l'URL les composants dynamiques. Essayez

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

Le deuxième problème avec votre code (et sans doute la raison de l'impression bizarre) est vous passez la chaîne directement à NSLog, il est donc d'être traité comme une chaîne de format. Vous devez utiliser

NSLog(@"%@", encodedString); 

à la place. Cela le fera imprimer comme prévu. Edit: Un troisième problème avec votre code est que vous mélangez des objets auto-libérés et possédés, puis les relâchez tous à la fin. Allez voir les 3 objets que vous créez et que vous publierez ultérieurement. L'un d'eux ne devrait pas être publié plus tard car il a été produit par une méthode qui ne commençait pas par les mots alloc, copy ou new. Identifier l'objet en question est un exercice laissé au lecteur.

+0

le point pris. Merci! – bcsantos

0

Vous pouvez prendre votre URL et de l'utilisation:

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

merci pour le pointeur :) – bcsantos

+0

NP ... la réponse ci-dessus est en effet plus correcte. Thx ... –

20

En fait, toutes les réponses précédentes contiennent au moins quelques inexactitudes, qui, pour de nombreuses valeurs communes de l'utilisateur fourni du texte dans les TextFields ne pas communiquer correctement avec le serveur

stringByAddingPercentEscapesUsingEncoding: pour cent échappe tous les caractères qui ne sont pas URL valide personnages. Cette méthode doit être appliquée une fois à l'URL entière.

Une réponse précédente prétend que stringByAddingPercentEscapesUsingEncoding: fonctionne comme les classes de construction d'URL dans de nombreux langages de script, où vous ne devez pas l'appliquer à l'ensemble de la chaîne d'URL, mais ce n'est pas le cas. N'importe qui peut facilement vérifier cela en vérifiant sa sortie pour & s et ? s non échappé. Il est donc bon de l'appliquer à l'intégralité de la chaîne, mais il ne suffit pas de l'appliquer à votre contenu d'URL "dynamique".

La réponse précédente est correcte dans la mesure où vous devez faire un peu plus de travail sur les noms et les valeurs qui vont dans votre chaîne de requête CGI. Depuis CGI est spécifié par RFC3875, cela est souvent appelé RFC3875 échapper à pourcentage.Il veille à ce que vos noms et les valeurs ne contiennent pas de caractères qui sont des caractères d'URL valides mais qui sont importantes dans d'autres parties de l'URL (;, ?, :, @, &, =, $, +, {, }, < Toutefois, il est très important de terminer également en effectuant des pourcentages d'URL clairs sur la chaîne complète pour s'assurer que tous les caractères de la chaîne sont des caractères d'URL valides. Bien que vous ne le fassiez pas dans votre exemple, en général, il peut y avoir des caractères dans une partie 'statique' de la chaîne qui ne sont pas des caractères d'URL valides, vous devez donc également leur échapper.

Malheureusement, NSString ne nous donne pas le pouvoir d'échapper aux caractères significatifs RFC3875 donc nous devons plonger dans CFString pour le faire. Il est évident que l'utilisation CFString est une douleur si j'ajoute généralement un Category sur NSString comme ceci:

@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 

Avec cette Category en place, le problème d'origine pourrait être résolu correctement avec ce qui suit:

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

Ceci est un peu lourd variable juste être plus clair. Notez également que la liste de variables fournie à stringWithFormat: ne doit pas être nil terminée. La chaîne de format décrit le nombre précis de variables qui devraient le suivre. En outre, techniquement, les chaînes pour les noms de chaînes de requête (nom, balises, entrée, ..) doivent être exécutées automatiquement par stringByAddingPercentEscapesUsingEncoding: mais dans ce petit exemple, nous pouvons facilement voir qu'elles ne contiennent aucun caractère URL invalide.

Pour voir pourquoi les solutions précédentes sont incorrectes, imaginez que le texte de saisie utilisateur dans dreamEntry.text contient un &, ce qui n'est pas improbable. Avec les solutions précédentes, tout le texte suivant ce caractère serait perdu au moment où le serveur recevrait ce texte, puisque l'esperluette non échappée serait interprétée par le serveur comme mettant fin à la partie valeur de cette paire de chaînes de requête.

+1

bravo. La réponse actuellement "correcte" est que nous pouvons tous voir un peu trop incorrect. * cependant * lorsque vous utilisez cette option pour échapper des valeurs de paramètres envoyées à l'application Twitter, les résultats sont brouillés (en fait seulement un groupe de% caractères). Si c'est un problème de décodage sur le compte du client Twitter ou non, je ne sais pas. Il fonctionne avec une autre solution utilisant CFURLCreateStringByAddingPercentEscapes() cependant. J'ai obtenu cette solution d'ici: http://wiki.akosma.com/IPhone_URL_Schemes#Note_about_URL_Encoding_in_Objective-C – Jonny

+0

L'implémentation de la catégorie que j'ai fournie est pratiquement identique à la solution que vous liez (elle utilise également CFURLCreateStringByAddingPercentEscapes() pour le lourd la différence principale est que la solution n'est pas enveloppée proprement). Si vous avez eu un problème avec la catégorie ci-dessus, je suppose que vous appliquiez à la fois stringByAddingRFC3875PercentEscapesUsingEncoding() et NSString stringByAddingPercentEscapesUsingEncoding() à la même chaîne, qui est mauvaise, car l'URL d'échappement n'est pas idempotente, donc vous commencez à échapper les échappements (par exemple.% 20 devient% 2520). – barrycburton

+0

En fait, cette solution est * presque * correcte. À savoir, l'appel à [self stringByAddingPercentEscapesUsingEncoding: encoding] est inutile, car CFURLCreateStringByAddingPercentEscapes() le fera déjà pour vous.La méthode devient ainsi: - (NSString *) stringByAddingRFC3875PercentEscapesUsingEncoding: (NSStringEncoding) de codage { CFStringEncoding cfEncoding = CFStringConvertNSStringEncodingToEncoding (encodage); NSString * rfcEscaped = (NSString *) CFURLCreateStringByAddingPercentEscapes (NULL, (CFStringRef) auto, NULL, (CFStringRef) @ "; /?: @ & = $ + {} <>,, CfEncoding); return [auto-libération rfcEscaped]; } – lensovet

Questions connexes