J'ai un NSString
comme ceci:
http://www.
mais je veux le transformer en:
http%3A%2F%2Fwww.
Comment puis-je faire ceci?
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éer un jeu de caractères combinant tout ce qui précède:
NSCharacterSet *URLCombinedCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@" \"#%/:<>?@[\\]^`{|}"] invertedSet];
Créer une base64
Dans le cas du 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: stringByAddingPercentEncodingWithAllowedCharacters
encodera également les caractères UTF-8 nécessitant un encodage.
Pré iOS7 utiliser Core Foundation
Utilisation 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: -stringByAddingPercentEscapesUsingEncoding
ne produira pas le bon codage, dans ce cas, il ne codera rien qui retourne la même chaîne.
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding
_ code 14 caractères:
`#% ^ {} [] | \" <> plus le caractère d'espace sous forme de pourcentage d'échappement.
testString:
" `~!@#$%^&*()_+-={}[]|\\:;\"'<,>.?/AZaz"
encodedString:
"%20%60~!@%23$%25%5E&*()_+-=%7B%7D%5B%5D%7C%5C:;%22'%3C,%3E.?/AZaz"
Remarque: déterminez si cet ensemble de caractères répond à vos besoins, sinon modifiez-les au besoin.
RFC 3986 caractères nécessitant un encodage (% ajouté puisqu'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 \"% -. <>\^ _ `{|} ~"
Cela s'appelle encodage d'URL . Plus ici .
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)self,
NULL,
(CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
CFStringConvertNSStringEncodingToEncoding(encoding));
}
Ce n'est pas ma solution. Quelqu'un d'autre a écrit dans stackoverflow mais j'ai oublié comment.
D'une certaine manière cette solution fonctionne "bien". Il gère les caractères chinois, diacritiques et pratiquement 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écierai vraiment. Fondamentalement, il a une explication sur la raison pour laquelle cette chaîne encodée décodera exactement comme elle le souhaite.
J'ai légèrement 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.Use CFBridgingRelease pour transtyper un objet de type Core Foundation en tant qu’objet Objective-C et transférer la propriété de l’objet vers ARC. Voir 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
NSString *str = (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)yourString,
NULL,
CFSTR("/:"),
kCFStringEncodingUTF8);
Vous devrez relâcher ou autorelease str
vous-même.
Google implémente cela dans leur Google Toolbox for Mac . C’est donc un bon endroit pour faire la meilleure chose au monde. Une autre option consiste à inclure la Boîte à outils et à utiliser leur implémentation.
Commander la mise en œuvre ici . (Ce qui revient exactement à ce que les gens ont posté ici).
C'est comme ça que je fais ça à Swift.
extension String {
func encodeURIComponent() -> String {
return self.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
}
func decodeURIComponent() -> String {
return self.componentsSeparatedByString("+").joinWithSeparator(" ").stringByRemovingPercentEncoding!
}
}
Voici ce que j'utilise. Notez que vous devez utiliser le @autoreleasepool
fonctionnalité ou le programme peut planter ou verrouiller l'IDE. 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 à maintes reprises et de nombreuses réponses ont été données, mais malheureusement, toutes les personnes sélectionnées (et quelques autres suggérées) ont tort.
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;
}
}