it-swarm.com.de

Wie kann ich einen String mit einer URL kodieren?

Ich habe eine URL-Zeichenfolge (NSString) mit Leerzeichen und &-Zeichen. Wie kodiere ich die gesamte Zeichenfolge (einschließlich des &-Zeichens und der Leerzeichen)?

180
xonegirlz

Leider funktioniert stringByAddingPercentEscapesUsingEncoding nicht immer zu 100%. Es codiert Nicht-URL-Zeichen, lässt jedoch die reservierten Zeichen (wie Schrägstrich / und kaufmännisches Und &) allein. Anscheinend ist dies ein bug, den Apple kennt, aber da sie es noch nicht behoben haben, benutze ich diese Kategorie, um einen String zu url-encode:

@implementation NSString (NSString_Extended)

- (NSString *)urlencode {
    NSMutableString *output = [NSMutableString string];
    const unsigned char *source = (const unsigned char *)[self UTF8String];
    int sourceLen = strlen((const char *)source);
    for (int i = 0; i < sourceLen; ++i) {
        const unsigned char thisChar = source[i];
        if (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;
}

So benutzt:

NSString *urlEncodedString = [@"SOME_URL_GOES_HERE" urlencode];

// Or, with an already existing string:
NSString *someUrlString = @"someURL";
NSString *encodedUrlStr = [someUrlString urlencode];

Das funktioniert auch:

NSString *encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
                            NULL,
                            (CFStringRef)unencodedString,
                            NULL,
                            (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                            kCFStringEncodingUTF8 );

Einige gute Lektüre zum Thema:

Objective-c iPhone Prozent kodieren eine Zeichenfolge?
Objective-C- und Swift-URL-Codierung

http://cybersam.com/programming/proper-url-percent-encoding-in-ios
https://devforums.Apple.com/message/15674#15674http://simonwoodside.com/weblog/2009/4/22/how_to_really_url_encode/

283
chown

Das könnte hilfreich sein

NSString *sampleUrl = @"http://www.google.com/search.jsp?params=Java Developer";
NSString* encodedUrl = [sampleUrl stringByAddingPercentEscapesUsingEncoding:
 NSUTF8StringEncoding];

Für iOS 7+ ist der empfohlene Weg:

NSString* encodedUrl = [sampleUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

Sie können den zulässigen Zeichensatz entsprechend der Anforderung der URL-Komponente auswählen.

122
Nishant

Seit der Auswahl der Antwort wurden neue APIs hinzugefügt. Sie können jetzt NSURLUtilities verwenden. Da unterschiedliche Teile von URLs unterschiedliche Zeichen zulassen, verwenden Sie den entsprechenden Zeichensatz. Das folgende Beispiel codiert für die Aufnahme in die Abfragezeichenfolge:

encodedString = [myString stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLQueryAllowedCharacterSet];

Um '&' speziell zu konvertieren, müssen Sie es aus dem URL-Abfragesatz entfernen oder einen anderen Satz verwenden, da in einer URL-Abfrage '&' zulässig ist:

NSMutableCharacterSet *chars = NSCharacterSet.URLQueryAllowedCharacterSet.mutableCopy;
[chars removeCharactersInRange:NSMakeRange('&', 1)]; // %26
encodedString = [myString stringByAddingPercentEncodingWithAllowedCharacters:chars];
89
Peter DeWeese

Swift 2.0-Beispiel (iOS 9 kompatibel)

extension String {

  func stringByURLEncoding() -> String? {

    let characters = NSCharacterSet.URLQueryAllowedCharacterSet().mutableCopy() as! NSMutableCharacterSet

    characters.removeCharactersInString("&")

    guard let encodedString = self.stringByAddingPercentEncodingWithAllowedCharacters(characters) else {
      return nil
    }

    return encodedString

  }

}
16
Oliver Atkinson

iOS 7 Update

NSString *encode = [string stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

NSString *decode = [encode stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
14
Underdog

Ich entschied mich für den Aufruf der Variable CFURLCreateStringByAddingPercentEscapes, wie durch die akzeptierte Antwort angegeben. In der neuesten Version von XCode (und IOS) führte dies jedoch zu einem Fehler. Stattdessen wurde Folgendes verwendet:

NSString *apiKeyRaw = @"79b|7Qd.jW=])(fv|M&W0O|3CENnrbNh4}2E|-)J*BCjCMrWy%dSfGs#A6N38Fo~";

NSString *apiKey = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)apiKeyRaw, NULL, (CFStringRef)@"!*'();:@&=+$,/?%#[]", kCFStringEncodingUTF8));
8
Mike Purcell

Versuchen Sie diestringByAddingPercentEncodingWithAllowedCharactersMethode mit[NSCharacterSet URLUserAllowedCharacterSet]zu verwenden, um alle Fälle abzudecken

Ziel c

NSString *value = @"Test / Test";
value = [value stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLUserAllowedCharacterSet]];

Schnell 

var value = "Test / Test"
value.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLUserAllowedCharacterSet())

Ausgabe

Test%20%2F%20Test

6
Alex

Nachdem ich alle Antworten zu diesem Thema gelesen und die ( falsch ) akzeptiert habe, möchte ich meinen Beitrag hinzufügen.

WENNdas Ziel ist iOS7 +, und 2017 sollte XCode es wirklich schwer machen, Kompatibilität unter iOS8 bereitzustellen. Der beste Weg, Thread-sicher, schnell. AMD bietet volle UTF-8-Unterstützung.

(Ziel-C-Code)

@implementation NSString (NSString_urlencoding)

- (NSString *)urlencode {
    static NSMutableCharacterSet *chars = nil;
    static dispatch_once_t pred;

    if (chars)
        return [self stringByAddingPercentEncodingWithAllowedCharacters:chars];

    // to be thread safe
    dispatch_once(&pred, ^{
        chars = NSCharacterSet.URLQueryAllowedCharacterSet.mutableCopy;
        [chars removeCharactersInString:@"!*'();:@&=+$,/?%#[]"];
    });
    return [self stringByAddingPercentEncodingWithAllowedCharacters:chars];
}
@end

Dies erweitert NSString, schließt RFC-verbotene Zeichen aus, unterstützt UTF-8-Zeichen und ermöglicht die Verwendung folgender Funktionen:

NSString *myusername = "I'm[evil]&want(to)break!!!$->àéìòù";
NSLog(@"Source: %@ -> Dest: %@", myusername, [myusername urlencode]);

Das wird auf Ihrer Debug-Konsole gedruckt:

Quelle: Ich bin [böse] und will brechen !!! !!! -> àéìòù -> Dest: I% 27m% 5Bevil% 5D% 26want% 28to% 29break% 21% 21% 21% 24-% 3E% C3 % A0% C3% A9% C3% AC% C3% B2% C3% B9

Beachten Sie auch die Verwendung von dispatch_once, um mehrfache Initialisierungen in Multithread-Umgebungen zu vermeiden.

5
gabry

Verwenden Sie NSURLComponents zum Kodieren von HTTP-GET-Parametern:

    var urlComponents = NSURLComponents(string: "https://www.google.de/maps/")!
    urlComponents.queryItems = [
        NSURLQueryItem(name: "q", value: String(51.500833)+","+String(-0.141944)),
        NSURLQueryItem(name: "z", value: String(6))
    ]
    urlComponents.URL     // returns https://www.google.de/maps/?q=51.500833,-0.141944&z=6

http://www.ralfebert.de/snippets/ios/encoding-nsurl-get-parameters/

4
Ralf Ebert

Hier ist ein produktionsbereiter flexibler Ansatz in Swift 4 :

public extension CharacterSet {

    public static let urlQueryParameterAllowed = CharacterSet.urlQueryAllowed.subtracting(CharacterSet(charactersIn: "&?"))

    public static let urlQueryDenied           = CharacterSet.urlQueryAllowed.inverted()
    public static let urlQueryKeyValueDenied   = CharacterSet.urlQueryParameterAllowed.inverted()
    public static let urlPathDenied            = CharacterSet.urlPathAllowed.inverted()
    public static let urlFragmentDenied        = CharacterSet.urlFragmentAllowed.inverted()
    public static let urlHostDenied            = CharacterSet.urlHostAllowed.inverted()

    public static let urlDenied                = CharacterSet.urlQueryDenied
        .union(.urlQueryKeyValueDenied)
        .union(.urlPathDenied)
        .union(.urlFragmentDenied)
        .union(.urlHostDenied)


    public func inverted() -> CharacterSet {
        var copy = self
        copy.invert()
        return copy
    }
}



public extension String {
    func urlEncoded(denying deniedCharacters: CharacterSet = .urlDenied) -> String? {
        return addingPercentEncoding(withAllowedCharacters: deniedCharacters.inverted())
    }
}

Verwendungsbeispiel:

print("Hello, World!".urlEncoded()!)
print("You&Me?".urlEncoded()!)
print("#Blessed 100%".urlEncoded()!)
print("Pride and Prejudice".urlEncoded(denying: .uppercaseLetters)!)

Ausgabe:

Hello,%20World!
You%26Me%3F
%23Blessed%20100%25
%50ride and %50rejudice
4
Ben Leggiero

Swift-Code basierend auf der Antwort von chown in diesem Thread. 

extension String {
    func urlEncode() -> String {
        return CFURLCreateStringByAddingPercentEscapes(
            nil,
            self,
            nil,
            "!*'();:@&=+$,/?%#[]",
            CFStringBuiltInEncodings.UTF8.rawValue
        )
    }
}
4
neoneye

Dieser Code hat mir beim Kodieren von Sonderzeichen geholfen

NSString* encPassword = [password stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet alphanumericCharacterSet]];
3
Rupesh Baldania

In Swift 3:

// exclude alpha and numeric == "full" encoding
stringUrl = stringUrl.addingPercentEncoding(withAllowedCharacters: .alphanumerics)!;

// exclude hostname and symbols &,/ and etc
stringUrl = stringUrl.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!;
2
sea-kg

In Swift 3 bitte unten testen:

let stringURL = "YOUR URL TO BE ENCODE";
let encodedURLString = stringURL.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
print(encodedURLString)

Da stringByAddingPercentEscapesUsingEncoding keine URL-Zeichen codiert, aber die reservierten Zeichen (wie !*'();:@&=+$,/?%#[]) belässt, können Sie die URL wie folgt codieren:

let stringURL = "YOUR URL TO BE ENCODE";
let characterSetTobeAllowed = (CharacterSet(charactersIn: "!*'();:@&=+$,/?%#[] ").inverted)
if let encodedURLString = stringURL.addingPercentEncoding(withAllowedCharacters: characterSetTobeAllowed) {
    print(encodedURLString)
}
2
Dinesh
-(NSString *)encodeUrlString:(NSString *)string {
  return CFBridgingRelease(
                    CFURLCreateStringByAddingPercentEscapes(
                        kCFAllocatorDefault,
                        (__bridge CFStringRef)string,
                        NULL,
                        CFSTR("!*'();:@&=+$,/?%#[]"),
                        kCFStringEncodingUTF8)
                    );
}

nach dem folgenden Blog

1
Anton Kashpor

In meinem Fall, wo die letzte Komponente arabische Buchstaben war, habe ich Folgendes in Swift 2.2 gemacht:

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

verwendungszweck:

let stringURL = "http://xxx.dev.com/endpoint/nonLatinCharacters"

if let encodedStringURL = stringURL.encodeUTF8() {

    if let url = NSURL(string: encodedStringURL) {

      ...
    }

} 
1
Bobj-C

Ich hatte ein ähnliches Problem, indem ich komplexe Zeichenfolgen als Parameter POST übergab. Meine Zeichenfolgen können asiatische Zeichen, Leerzeichen, Anführungszeichen und alle Arten von Sonderzeichen enthalten. Die Lösung, die ich schließlich fand, bestand darin, meinen String in die passende Reihe von Unicodes umzuwandeln, z. "Hu0040Hu0020Hu03f5 ...." mit [NSString stringWithFormat: @ "Hu% 04x", [string characterAtIndex: i]], um den Unicode von jedem Zeichen in der Originalzeichenfolge abzurufen. Dasselbe kann in Java gemacht werden.

Diese Zeichenfolge kann sicher als POST - Parameter übergeben werden.

Auf der Serverseite (PHP) ändere ich alle "H" in "\" und gebe die resultierende Zeichenfolge an json_decode weiter. Der letzte Schritt besteht darin, einzelne Anführungszeichen vor dem Speichern der Zeichenfolge in MySQL zu schützen.

Auf diese Weise kann ich jeden UTF8-String auf meinem Server speichern.

0
Georges

// Das ist ohne Test

NSMutableCharacterSet* set = [[NSCharacterSet alphanumericCharacterSet] mutableCopy];
[set addCharactersInString:@"-_.~"];
NSString *encode = [test stringByAddingPercentEncodingWithAllowedCharacters:set];
0
Achilles Wang

Dieser arbeitet für mich.

func stringByAddingPercentEncodingForFormData(plusForSpace: Bool=false) -> String? {
    let unreserved = "*-._"
    let allowed = NSMutableCharacterSet.alphanumericCharacterSet()
    allowed.addCharactersInString(unreserved)

    if plusForSpace {
        allowed.addCharactersInString(" ")
    }

    var encoded = stringByAddingPercentEncodingWithAllowedCharacters(allowed)
    if plusForSpace {
        encoded = encoded?.stringByReplacingOccurrencesOfString(" ",
                                                                withString: "+")
    }
    return encoded
}

Ich habe die obige Funktion über diesen Link gefunden: http://useyourloaf.com/blog/how-to-percent-encode-a-url-string/

Sie können diese Funktion auch mit der Swift-Erweiterung verwenden. Bitte lassen Sie mich wissen, wenn es Probleme gibt.

0
Gaurav Singla

Für einzelne www-formcodierte Abfrageparameter habe ich eine Kategorie für NSString erstellt:

- (NSString*)WWWFormEncoded{
     NSMutableCharacterSet *chars = NSCharacterSet.alphanumericCharacterSet.mutableCopy;
     [chars addCharactersInString:@" "];
     NSString* encodedString = [self stringByAddingPercentEncodingWithAllowedCharacters:chars];
     encodedString = [encodedString stringByReplacingOccurrencesOfString:@" " withString:@"+"];
     return encodedString;
}
0
Pete Kamm

Apples Ratschlag in den Versionshinweisen zu 10.11 lautet:

Wenn Sie eine gesamte URL-Zeichenfolge prozentual codieren müssen, können Sie mit diesem Code einen NSString codieren, der als URL gedacht ist (in urlStringToEncode):

NSString *percentEncodedURLString =
  [[NSURL URLWithDataRepresentation:[urlStringToEncode dataUsingEncoding:NSUTF8StringEncoding] relativeToURL:nil] relativeString];
0
nithinbhaktha