Ersatz für stringByAddingPercentEscapesUsingEncoding in ios9?


112

In iOS8 und früheren Versionen kann ich Folgendes verwenden:

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

in iOS9 stringByAddingPercentEscapesUsingEncodingwurde ersetzt durch stringByAddingPercentEncodingWithAllowedCharacters:

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

und meine Frage ist: Wo finde ich benötigt NSCharacterSet( NSUTF8StringEncoding) für den richtigen Ersatz von stringByAddingPercentEscapesUsingEncoding?

Antworten:


131

Die Abwertungsnachricht lautet (Hervorhebung von mir):

Verwenden Sie stattdessen stringByAddingPercentEncodingWithAllowedCharacters (_ :), das immer die empfohlene UTF-8-Codierung verwendet und für eine bestimmte URL-Komponente oder Unterkomponente codiert, da jede URL-Komponente oder Unterkomponente unterschiedliche Regeln für die Gültigkeit der Zeichen hat.

Sie müssen also nur ein adäquates NSCharacterSetArgument angeben. Glücklicherweise gibt es für URLs eine sehr praktische Klassenmethode URLHostAllowedCharacterSet, die Sie wie folgt verwenden können:

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

Update für Swift 3 - Die Methode wird zur statischen Eigenschaft urlHostAllowed:

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

Beachten Sie jedoch Folgendes:

Diese Methode soll eine URL-Komponente oder Unterkomponentenzeichenfolge prozentual codieren, NICHT eine gesamte URL-Zeichenfolge.


6
Außerdem würde ich dringend empfehlen NSURLComponents, die prozentuale Codierung für Sie zu verwenden.
Antonio Favata

1
Irgendwelche Vorschläge, was für die gesamte URL-Zeichenfolge verwendet werden soll?
Fähigkeit M2

1
@ SkillM2 Ich denke NSURLComponents(mit jeder Komponente, die prozentual mit der entsprechenden codiert NSCharacterSetist), ist der richtige Weg.
Antonio Favata

2
Sie sollten niemals versuchen, eine ganze URL-Zeichenfolge zu codieren. Dies kann zu unerwarteten Fehlern und in einigen Fällen zu Sicherheitslücken führen. Die einzig garantierte korrekte Methode zum Codieren einer URL besteht darin, sie einzeln auszuführen.
Dgatwood

Toll. Vielen Dank, Kumpel!
Felipe

100

Für Ziel-C:

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

Wo finde ich Set für NSUTF8StringEncoding?

Es gibt vordefinierte Zeichensätze für die sechs URL-Komponenten und Unterkomponenten, die eine prozentuale Codierung ermöglichen. Diese Zeichensätze werden an übergeben -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

Die Abwertungsnachricht lautet (Hervorhebung von mir):

Verwenden Sie stattdessen stringByAddingPercentEncodingWithAllowedCharacters (_ :), das immer die empfohlene UTF-8-Codierung verwendet und für eine bestimmte URL-Komponente oder Unterkomponente codiert, da jede URL-Komponente oder Unterkomponente unterschiedliche Regeln für die Gültigkeit der Zeichen hat.

Sie müssen also nur ein adäquates NSCharacterSetArgument angeben. Glücklicherweise gibt es für URLs eine sehr praktische Klassenmethode URLHostAllowedCharacterSet, die Sie wie folgt verwenden können:

NSCharacterSet *set = [NSCharacterSet URLHostAllowedCharacterSet]; 

Beachten Sie jedoch Folgendes:

Diese Methode soll eine URL-Komponente oder Unterkomponentenzeichenfolge prozentual codieren, NICHT eine gesamte URL-Zeichenfolge.


4
Ich liebe es, wenn Apple das Leben leichter macht. Danke Apfel.
Ente

5
Was bedeutet "Diese Methode dient zum prozentualen Codieren einer URL-Komponente oder Unterkomponentenzeichenfolge, NICHT einer gesamten URL-Zeichenfolge." ?
GeneCode

4
URLHostAllowedCharacterSet gab den Fehler "Nicht unterstützte URL" aus. Ich habe URLFragmentAllowedCharacterSet verwendet und es funktioniert einwandfrei.
anoop4real

1
Dies funktioniert nicht mit +, es wird es nicht codieren und es wird wie durch die Spezifikation durch Speicherplatz auf der Serverseite ersetzt.
Torge

45

URLHostAllowedCharacterSetarbeitet nicht für mich. Ich benutze URLFragmentAllowedCharacterSetstattdessen.

ZIEL C

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

SWIFT - 4

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

Die folgenden nützlichen (invertierten) Zeichensätze sind:

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

Danke und dir auch
Arpit B Parekh

Bemerkenswert ist, dass keines dieser Sets enthält +. Pluszeichen in der Zeichenfolge werden also durcheinander gebracht, wenn sie in Abfrageparametern weitergegeben werden - auf der Serverseite als Leerzeichen `` behandelt.
Asmo Soinio

21

Ziel c

Dieser Code funktioniert für mich:

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

Für Swift 3.0

Sie können urlHostAllowedCharacterSet verwenden.

/// Gibt den Zeichensatz für Zeichen zurück, die in einer Host-URL-Unterkomponente zulässig sind.

public static var urlHostAllowed: CharacterSet { get }

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

1

Was bedeutet "Diese Methode dient zum prozentualen Codieren einer URL-Komponente oder Unterkomponentenzeichenfolge, NICHT einer gesamten URL-Zeichenfolge." ? - GeneCode 1. September 16 um 8:30 Uhr

Es bedeutet, dass Sie nicht https://xpto.example.com/path/subpathdie URL codieren sollen , sondern nur das, was nach der URL geht ?.

Angenommen, es gibt Anwendungsfälle dafür in folgenden Fällen:

https://example.com?redirectme=xxxxx

Wo xxxxxist eine vollständig verschlüsselte URL.


0

Hinzufügen zur akzeptierten Antwort. Unter Berücksichtigung dieses Hinweises

Diese Methode soll eine URL-Komponente oder Unterkomponentenzeichenfolge prozentual codieren, NICHT eine gesamte URL-Zeichenfolge.

Die gesamte URL sollte nicht verschlüsselt werden:

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!
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.