Remplacement de stringByAddingPercentEscapesUsingEncoding dans ios9?

112

Dans iOS8 et les versions antérieures, je peux utiliser:

NSString *str = ...; // some URL
NSString *result = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

dans iOS9 stringByAddingPercentEscapesUsingEncodinga été remplacé par stringByAddingPercentEncodingWithAllowedCharacters:

NSString *str = ...; // some URL
NSCharacterSet *set = ???; // where to find set for NSUTF8StringEncoding?
NSString *result = [str stringByAddingPercentEncodingWithAllowedCharacters:set];

et ma question est: où trouver nécessaire NSCharacterSet( NSUTF8StringEncoding) pour un remplacement approprié de stringByAddingPercentEscapesUsingEncoding?

Slavik
la source

Réponses:

131

Le message d'obsolescence dit (c'est moi qui souligne):

Utilisez à la place stringByAddingPercentEncodingWithAllowedCharacters (_ :), qui utilise toujours le codage UTF-8 recommandé et qui code pour un composant ou sous-composant URL spécifique puisque chaque composant ou sous-composant URL a des règles différentes pour les caractères valides.

Il vous suffit donc de fournir un NSCharacterSetargument adéquat . Heureusement, pour les URL, il existe une méthode de classe très pratique appelée URLHostAllowedCharacterSetque vous pouvez utiliser comme ceci:

let encodedHost = unencodedHost.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())

Mise à jour pour Swift 3 - la méthode devient la propriété statique urlHostAllowed:

let encodedHost = unencodedHost.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)

Sachez cependant que:

Cette méthode est destinée à encoder en pourcentage un composant URL ou une chaîne de sous-composant, PAS une chaîne URL entière.

Antonio Favata
la source
6
En outre, je suggère fortement d'utiliser NSURLComponents, qui peut gérer le codage en pourcentage pour vous.
Antonio Favata
1
Des suggestions sur ce qu'il faut utiliser pour toute la chaîne d'URL?
Skill M2
1
@ SkillM2 Je pense NSURLComponents(avec chaque composant codé en pourcentage avec le correspondant NSCharacterSet) est la bonne voie à suivre.
Antonio Favata
2
Vous ne devez jamais, jamais, tenter de coder une chaîne URL entière. Cela peut provoquer des bogues inattendus et, dans certains cas, des failles de sécurité. La seule façon correcte et correcte d'encoder une URL est de le faire un morceau à la fois.
dgatwood
Génial. Merci beaucoup, mon pote!
Felipe
100

Pour Objective-C :

NSString *str = ...; // some URL
NSCharacterSet *set = [NSCharacterSet URLHostAllowedCharacterSet]; 
NSString *result = [str stringByAddingPercentEncodingWithAllowedCharacters:set];

où trouver ensemble pour NSUTF8StringEncoding?

Il existe des jeux de caractères prédéfinis pour les six composants et sous-composants URL qui permettent un codage en pourcentage. Ces jeux de caractères sont transmis à -stringByAddingPercentEncodingWithAllowedCharacters:.

 // Predefined character sets for the six URL components and subcomponents which allow percent encoding. These character sets are passed to -stringByAddingPercentEncodingWithAllowedCharacters:.
@interface NSCharacterSet (NSURLUtilities)
+ (NSCharacterSet *)URLUserAllowedCharacterSet;
+ (NSCharacterSet *)URLPasswordAllowedCharacterSet;
+ (NSCharacterSet *)URLHostAllowedCharacterSet;
+ (NSCharacterSet *)URLPathAllowedCharacterSet;
+ (NSCharacterSet *)URLQueryAllowedCharacterSet;
+ (NSCharacterSet *)URLFragmentAllowedCharacterSet;
@end

Le message d'obsolescence dit (c'est moi qui souligne):

Utilisez à la place stringByAddingPercentEncodingWithAllowedCharacters (_ :), qui utilise toujours le codage UTF-8 recommandé et qui code pour un composant ou sous-composant URL spécifique puisque chaque composant ou sous-composant URL a des règles différentes pour les caractères valides.

Il vous suffit donc de fournir un NSCharacterSetargument adéquat . Heureusement, pour les URL, il existe une méthode de classe très pratique appelée URLHostAllowedCharacterSetque vous pouvez utiliser comme ceci:

NSCharacterSet *set = [NSCharacterSet URLHostAllowedCharacterSet]; 

Sachez cependant que:

Cette méthode est destinée à encoder en pourcentage un composant URL ou une chaîne de sous-composant, PAS une chaîne URL entière.

ElonChan
la source
4
J'adore quand Apple facilite la vie. Merci Apple.
Canard
5
Quelle est la signification de "Cette méthode est destinée à encoder en pourcentage un composant URL ou une chaîne de sous-composants, PAS une chaîne URL entière." ?
GeneCode le
4
URLHostAllowedCharacterSet donnait l'erreur "URL non prise en charge", j'ai utilisé URLFragmentAllowedCharacterSet et son fonctionnement fonctionne correctement.
anoop4real
1
cela ne fonctionne pas avec + il ne l'encodera pas et il sera remplacé par de l'espace côté serveur comme par spécification.
Torge
45

URLHostAllowedCharacterSetest NE FONCTIONNE PAS POUR MOI. J'utilise à la URLFragmentAllowedCharacterSetplace.

OBJECTIF C

NSCharacterSet *set = [NSCharacterSet URLFragmentAllowedCharacterSet];
NSString * encodedString = [@"url string" stringByAddingPercentEncodingWithAllowedCharacters:set];

SWIFT - 4

"url string".addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)

Les jeux de caractères suivants sont utiles (inversés):

URLFragmentAllowedCharacterSet  "#%<>[\]^`{|}
URLHostAllowedCharacterSet      "#%/<>?@\^`{|}
URLPasswordAllowedCharacterSet  "#%/:<>?@[\]^`{|}
URLPathAllowedCharacterSet      "#%;<>?[\]^`{|}
URLQueryAllowedCharacterSet     "#%<>[\]^`{|}
URLUserAllowedCharacterSet      "#%/:<>?@[\]^`
Lal Krishna
la source
Merci et même à vous aussi
Arpit B Parekh
Il convient de noter qu'aucun de ces ensembles ne comprend +. Ainsi, les signes plus dans la chaîne seront gâchés s'ils sont passés dans les paramètres de requête - traités comme un espace `` côté serveur.
Asmo Soinio le
21

Objectif c

ce code fonctionne pour moi:

urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]];
Bilal L
la source
4

Swift 2.2:

extension String {
 func encodeUTF8() -> String? {
//If I can create an NSURL out of the string nothing is wrong with it
if let _ = NSURL(string: self) {

    return self
}

//Get the last component from the string this will return subSequence
let optionalLastComponent = self.characters.split { $0 == "/" }.last


if let lastComponent = optionalLastComponent {

    //Get the string from the sub sequence by mapping the characters to [String] then reduce the array to String
    let lastComponentAsString = lastComponent.map { String($0) }.reduce("", combine: +)


    //Get the range of the last component
    if let rangeOfLastComponent = self.rangeOfString(lastComponentAsString) {
        //Get the string without its last component
        let stringWithoutLastComponent = self.substringToIndex(rangeOfLastComponent.startIndex)


        //Encode the last component
        if let lastComponentEncoded = lastComponentAsString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.alphanumericCharacterSet()) {


        //Finally append the original string (without its last component) to the encoded part (encoded last component)
        let encodedString = stringWithoutLastComponent + lastComponentEncoded

            //Return the string (original string/encoded string)
            return encodedString
        }
    }
}

return nil;
}
}
Bobj-C
la source
2

Pour Swift 3.0

Vous pouvez utiliser urlHostAllowedcharacterSet.

/// Renvoie le jeu de caractères pour les caractères autorisés dans un sous-composant URL hôte.

public static var urlHostAllowed: CharacterSet { get }

WebserviceCalls.getParamValueStringForURLFromDictionary(settingsDict as! Dictionary<String, AnyObject>).addingPercentEncoding(withAllowedCharacters: CharacterSet.urlHostAllowed)
technerd
la source
1

Quelle est la signification de "Cette méthode est destinée à encoder en pourcentage un composant URL ou une chaîne de sous-composants, PAS une chaîne URL entière." ? - GeneCode le 1 septembre 16 à 8h30

Cela signifie que vous n'êtes pas censé encoder le https://xpto.example.com/path/subpathde l'url, mais seulement ce qui suit le ?.

Supposé, car il existe des cas d'utilisation pour le faire dans des cas tels que:

https://example.com?redirectme=xxxxx

xxxxxest une URL entièrement codée.

kindaian
la source
0

Ajout à la réponse acceptée. Prenant en considération cette note

Cette méthode est destinée à encoder en pourcentage un composant URL ou une chaîne de sous-composant, PAS une chaîne URL entière.

l'URL entière ne doit pas être encodée:

let param = "=color:green|\(latitude),\(longitude)&\("zoom=13&size=\(width)x\(height)")&sensor=true&key=\(staticMapKey)".addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) 
let url = "https://maps.google.com/maps/api/staticmap?markers" + param!
Ayman Ibrahim
la source