Réponses:
Pour échapper aux personnages que vous voulez, c'est un peu plus de travail.
Exemple de code
iOS7 et supérieur:
NSString *unescaped = @"http://www";
NSString *escapedString = [unescaped stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
NSLog(@"escapedString: %@", escapedString);
Sortie NSLog:
escapedString: http% 3A% 2F% 2Fwww
Voici des jeux de caractères de codage d'URL utiles:
URLFragmentAllowedCharacterSet "#%<>[\]^`{|}
URLHostAllowedCharacterSet "#%/<>?@\^`{|}
URLPasswordAllowedCharacterSet "#%/:<>?@[\]^`{|}
URLPathAllowedCharacterSet "#%;<>?[\]^`{|}
URLQueryAllowedCharacterSet "#%<>[\]^`{|}
URLUserAllowedCharacterSet "#%/:<>?@[\]^`
Création d'un jeu de caractères combinant tout ce qui précède:
NSCharacterSet *URLCombinedCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@" \"#%/:<>?@[\\]^`{|}"] invertedSet];
Créer un Base64
Dans le cas d'un jeu de caractères Base64:
NSCharacterSet *URLBase64CharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@"/+=\n"] invertedSet];
Pour Swift 3.0:
var escapedString = originalString.addingPercentEncoding(withAllowedCharacters:.urlHostAllowed)
Pour Swift 2.x:
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())
Remarque: stringByAddingPercentEncodingWithAllowedCharactersencodera également les caractères UTF-8 nécessitant un encodage.
Avant iOS7, utilisez Core Foundation à l'
aide de Core Foundation avec ARC:
NSString *escapedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef) unescaped,
NULL,
CFSTR("!*'();:@&=+$,/?%#[]\" "),
kCFStringEncodingUTF8));
Utilisation de Core Foundation sans ARC:
NSString *escapedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)unescaped,
NULL,
CFSTR("!*'();:@&=+$,/?%#[]\" "),
kCFStringEncodingUTF8);
Remarque: -stringByAddingPercentEscapesUsingEncodingne produira pas l'encodage correct, dans ce cas, il n'encodera rien retournant la même chaîne.
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding encode 14 caractères:
`#% ^ {} [] | \" <> plus le caractère d'espace sous forme de pourcentage échappé.
testString:
" `~!@#$%^&*()_+-={}[]|\\:;\"'<,>.?/AZaz"
encodedString:
"%20%60~!@%23$%25%5E&*()_+-=%7B%7D%5B%5D%7C%5C:;%22'%3C,%3E.?/AZaz"
Remarque: considérez si cet ensemble de caractères répond à vos besoins, sinon modifiez-les si nécessaire.
Caractères RFC 3986 nécessitant un encodage (% ajouté car il s'agit du caractère de préfixe d'encodage):
"! # $ & '() * +, /:; =? @ []%"
Certains "caractères non réservés" sont en outre codés:
"\ n \ r \"% -. <> \ ^ _ `{|} ~"
-stringByAddingPercentEscapesUsingEncodingméthode de NSString .
stringByAddingPercentEscapesUsingEncodingcomportement funky . Il n'encode que «&» et «=» ou quelque chose de ridicule comme ça.
NSStringavec characterSetWithCharactersInString, prenez l'inverse avec invertedSetet utilisez-le avec stringByAddingPercentEncodingWithAllowedCharacters. Pour un exemple, voir cette réponse SO .
C'est ce qu'on appelle le codage d'URL . Plus ici .
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)self,
NULL,
(CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
CFStringConvertNSStringEncodingToEncoding(encoding));
}
CFURLCreateStringByAddingPercentEscapes()est obsolète. Utilisez [NSString stringByAddingPercentEncodingWithAllowedCharacters:]plutôt.
Ce n'est pas ma solution. Quelqu'un d'autre a écrit dans stackoverflow mais j'ai oublié comment.
D'une manière ou d'une autre, cette solution fonctionne "bien". Il gère les caractères diacritiques, chinois et à peu près tout le reste.
- (NSString *) URLEncodedString {
NSMutableString * output = [NSMutableString string];
const char * source = [self UTF8String];
int sourceLen = strlen(source);
for (int i = 0; i < sourceLen; ++i) {
const unsigned char thisChar = (const unsigned char)source[i];
if (false && thisChar == ' '){
[output appendString:@"+"];
} else if (thisChar == '.' || thisChar == '-' || thisChar == '_' || thisChar == '~' ||
(thisChar >= 'a' && thisChar <= 'z') ||
(thisChar >= 'A' && thisChar <= 'Z') ||
(thisChar >= '0' && thisChar <= '9')) {
[output appendFormat:@"%c", thisChar];
} else {
[output appendFormat:@"%%%02X", thisChar];
}
}
return output;
}
Si quelqu'un me disait qui a écrit ce code, je l'apprécierais vraiment. En gros, il a une explication sur la raison pour laquelle cette chaîne encodée décodera exactement comme il le souhaite.
J'ai un peu modifié sa solution. J'aime que l'espace soit représenté avec% 20 plutôt que +. C'est tout.
NSString * encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(NUL,(CFStringRef)@"parameter",NULL,(CFStringRef)@"!*'();@&+$,/?%#[]~=_-.:",kCFStringEncodingUTF8 );
NSURL * url = [[NSURL alloc] initWithString:[@"address here" stringByAppendingFormat:@"?cid=%@",encodedString, nil]];
Cela peut fonctionner dans Objective C ARC.Utilisez CFBridgingRelease pour convertir un objet de style Core Foundation en objet Objective-C et transférer la propriété de l'objet à ARC .Voir la fonction CFBridgingRelease ici.
+ (NSString *)encodeUrlString:(NSString *)string {
return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes
(kCFAllocatorDefault,
(__bridge CFStringRef)string,
NULL,
CFSTR("!*'();:@&=+$,/?%#[]"),
kCFStringEncodingUTF8)
);}
Swift iOS:
Juste pour information: j'ai utilisé ceci:
extension String {
func urlEncode() -> CFString {
return CFURLCreateStringByAddingPercentEscapes(
nil,
self,
nil,
"!*'();:@&=+$,/?%#[]",
CFStringBuiltInEncodings.UTF8.rawValue
)
}
}// end extension String
Voici ce que j'utilise. Notez que vous devez utiliser la @autoreleasepoolfonctionnalité ou le programme pourrait planter ou bloquer l'EDI. J'ai dû redémarrer mon IDE trois fois jusqu'à ce que je réalise le correctif. Il semble que ce code soit conforme à l'ARC.
Cette question a été posée à plusieurs reprises et de nombreuses réponses ont été données, mais malheureusement toutes celles sélectionnées (et quelques autres suggérées) sont fausses.
Voici la chaîne de test que j'ai utilisée: This is my 123+ test & test2. Got it?!
Voici mes méthodes de classe Objective C ++:
static NSString * urlDecode(NSString *stringToDecode) {
NSString *result = [stringToDecode stringByReplacingOccurrencesOfString:@"+" withString:@" "];
result = [result stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return result;
}
static NSString * urlEncode(NSString *stringToEncode) {
@autoreleasepool {
NSString *result = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)stringToEncode,
NULL,
(CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
kCFStringEncodingUTF8
));
result = [result stringByReplacingOccurrencesOfString:@"%20" withString:@"+"];
return result;
}
}
Google l'implémente dans sa boîte à outils Google pour Mac . C'est donc un bon endroit pour savoir comment ils le font. Une autre option consiste à inclure la boîte à outils et à utiliser leur implémentation.
Découvrez la mise en œuvre ici . (Ce qui revient exactement à ce que les gens ont publié ici).
C'est ainsi que je fais cela rapidement.
extension String {
func encodeURIComponent() -> String {
return self.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
}
func decodeURIComponent() -> String {
return self.componentsSeparatedByString("+").joinWithSeparator(" ").stringByRemovingPercentEncoding!
}
}
// utilise la méthode d'instance NSString comme ceci:
+ (NSString *)encodeURIComponent:(NSString *)string
{
NSString *s = [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return s;
}
+ (NSString *)decodeURIComponent:(NSString *)string
{
NSString *s = [string stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return s;
}
rappelez-vous, vous ne devez encoder ou décoder que la valeur de votre paramètre, pas toutes les URL que vous demandez.
int strLength = 0;
NSString *urlStr = @"http://www";
NSLog(@" urlStr : %@", urlStr );
NSMutableString *mutableUrlStr = [urlStr mutableCopy];
NSLog(@" mutableUrlStr : %@", mutableUrlStr );
strLength = [mutableUrlStr length];
[mutableUrlStr replaceOccurrencesOfString:@":" withString:@"%3A" options:NSCaseInsensitiveSearch range:NSMakeRange(0, strLength)];
NSLog(@" mutableUrlStr : %@", mutableUrlStr );
strLength = [mutableUrlStr length];
[mutableUrlStr replaceOccurrencesOfString:@"/" withString:@"%2F" options:NSCaseInsensitiveSearch range:NSMakeRange(0, strLength)];
NSLog(@" mutableUrlStr : %@", mutableUrlStr );
ùÕ9y^VêÏÊEØ®.ú/V÷ÅÖêú2Èh~- aucune des solutions ci-dessous ne semble résoudre ce problème!