Sostituzione per stringByAddingPercentEscapesUsingEncoding in ios9?


112

In iOS8 e precedenti posso usare:

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

in iOS9 stringByAddingPercentEscapesUsingEncodingè stato sostituito con stringByAddingPercentEncodingWithAllowedCharacters:

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

e la mia domanda è: dove trovare la necessaria NSCharacterSet( NSUTF8StringEncoding) per una corretta sostituzione di stringByAddingPercentEscapesUsingEncoding?

Risposte:


131

Il messaggio di deprecazione dice (enfasi mia):

Utilizza invece stringByAddingPercentEncodingWithAllowedCharacters (_ :), che utilizza sempre la codifica UTF-8 consigliata e che codifica per un componente o sottocomponente URL specifico poiché ogni componente o sottocomponente URL ha regole diverse per i caratteri validi.

Quindi è sufficiente fornire un NSCharacterSetargomento adeguato . Fortunatamente, per gli URL esiste un metodo di classe molto utile chiamato URLHostAllowedCharacterSetche puoi usare in questo modo:

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

Aggiornamento per Swift 3 : il metodo diventa la proprietà statica urlHostAllowed:

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

Tieni presente, tuttavia, che:

Questo metodo ha lo scopo di codificare in percentuale un componente URL o una stringa sottocomponente, NON un'intera stringa URL.


6
Inoltre, suggerisco vivamente di utilizzare NSURLComponents, che può gestire la codifica percentuale per te.
Antonio Favata

1
Qualche suggerimento su cosa usare per l'intera stringa dell'URL?
Skill M2

1
@ SkillM2 penso che NSURLComponents(con ogni componente codificato in percentuale con il corrispondente NSCharacterSet) sia la strada giusta da percorrere.
Antonio Favata

2
Non dovresti mai, mai, mai tentare di codificare un'intera stringa URL. Può causare bug imprevisti e, in alcuni casi, falle di sicurezza. L'unico modo corretto garantito per codificare un URL è farlo un pezzo alla volta.
dgatwood

Grande. Grazie mille, amico!
Felipe

100

Per Objective-C :

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

dove trovare il set per NSUTF8StringEncoding?

Esistono set di caratteri predefiniti per i sei componenti e sottocomponenti URL che consentono la codifica percentuale. Questi set di caratteri vengono passati a -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

Il messaggio di deprecazione dice (enfasi mia):

Utilizza invece stringByAddingPercentEncodingWithAllowedCharacters (_ :), che utilizza sempre la codifica UTF-8 consigliata e che codifica per un componente o sottocomponente URL specifico poiché ogni componente o sottocomponente URL ha regole diverse per i caratteri validi.

Quindi è sufficiente fornire un NSCharacterSetargomento adeguato . Fortunatamente, per gli URL esiste un metodo di classe molto utile chiamato URLHostAllowedCharacterSetche puoi usare in questo modo:

NSCharacterSet *set = [NSCharacterSet URLHostAllowedCharacterSet]; 

Tieni presente, tuttavia, che:

Questo metodo ha lo scopo di codificare in percentuale un componente URL o una stringa sottocomponente, NON un'intera stringa URL.


4
Adoro quando Apple semplifica la vita. Grazie Apple.
Duck

5
Qual è il significato di "Questo metodo ha lo scopo di codificare in percentuale un componente URL o una stringa sottocomponente, NON un'intera stringa URL". ?
GeneCode

4
URLHostAllowedCharacterSet stava dando l'errore "URL non supportato", ho usato URLFragmentAllowedCharacterSet e funziona bene.
anoop4real

1
questo non funziona con + non lo codificherà e sarà sostituito da uno spazio sul lato server come da specifica.
Torge

45

URLHostAllowedCharacterSetè NON LAVORO PER ME. Io URLFragmentAllowedCharacterSetinvece uso .

OBIETTIVO -C

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

SWIFT - 4

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

I seguenti sono set di caratteri utili (invertiti):

URLFragmentAllowedCharacterSet  "#%<>[\]^`{|}
URLHostAllowedCharacterSet      "#%/<>?@\^`{|}
URLPasswordAllowedCharacterSet  "#%/:<>?@[\]^`{|}
URLPathAllowedCharacterSet      "#%;<>?[\]^`{|}
URLQueryAllowedCharacterSet     "#%<>[\]^`{|}
URLUserAllowedCharacterSet      "#%/:<>?@[\]^`

Grazie e lo stesso anche a te
Arpit B Parekh

Vale la pena notare che nessuno di questi set include +. Quindi i segni più nella stringa saranno incasinati se passati nei parametri di query - trattati come spazio `` sul lato server.
Asmo Soinio

21

Objective-C

questo codice funziona per me:

urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]];

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

2

Per Swift 3.0

Puoi usare urlHostAllowedcharacterSet.

/// Restituisce il set di caratteri per i caratteri consentiti in un sottocomponente URL host.

public static var urlHostAllowed: CharacterSet { get }

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

1

Qual è il significato di "Questo metodo ha lo scopo di codificare in percentuale un componente URL o una stringa sottocomponente, NON un'intera stringa URL". ? - GeneCode 1 settembre 16 alle 8:30

Significa che non dovresti codificare https://xpto.example.com/path/subpathl'URL, ma solo ciò che va dopo il ?.

Supposto, perché ci sono casi d'uso per farlo in casi come:

https://example.com?redirectme=xxxxx

Dove si xxxxxtrova un URL completamente codificato.


0

Aggiunta alla risposta accettata. Prendendo in considerazione questa nota

Questo metodo ha lo scopo di codificare in percentuale un componente URL o una stringa sottocomponente, NON un'intera stringa URL.

l'intero URL non deve essere codificato:

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!
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.