Tengo una cadena de URL (NSString) con espacios y & caracteres. ¿Cómo puedo url codificar toda la cadena (incluyendo la & y comercial de caracteres y espacios)?

InformationsquelleAutor xonegirlz | 2011-11-11

21 Comentarios

  1. 285

    Por desgracia, stringByAddingPercentEscapesUsingEncoding no siempre funciona 100%. Se codifica la no-URL personajes, pero las hojas de los caracteres reservados (como slash / y ampersand &) por sí sola. Al parecer, este es un error que Apple es consciente de, pero como no se han fijado todavía, he estado usando esta categoría de la url de codificar una cadena:

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

    Utilizado como esta:

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

    Esto también funciona:

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

    Una buena lectura sobre el tema:

    Objective-c para iPhone por ciento codificar una cadena?

    Objective-C y Swift de la codificación URL

    http://cybersam.com/programming/proper-url-percent-encoding-in-ios

    https://devforums.apple.com/message/15674#15674
    http://simonwoodside.com/weblog/2009/4/22/how_to_really_url_encode/

    • ¿Por qué usar un complejo de categoría como esta, en lugar de simplemente colocar abajo a CFURLCreateStringByAddingPercentescapes(), donde se puede especificar de forma explícita a los caracteres que desea escapar.
    • Sí, es común, no a muchas maneras de código. Probablemente se me dio de la nueva años, justo ahora fro mi código. Que hay dos preguntas similares a sólo horas de diferencia, yo sospecho que era de la clase de tareas. 🙂
    • debido a que la función CF trabaja en un modelo inclusivo («escapar de estos personajes»), y por lo general, usted quiere trabajar en un exclusivo modelo («escapar de todo lo que excepto que estos personajes»)
    • href=»http://stackoverflow.com/questions/3423545/objective-c-iphone-percent-encode-a-string/3426140#3426140″>Boy que categoría método seguro de aspecto familiar!
    • Que puede ser el lugar donde la tengo. Ha sido una de categoría estándar en todos mis proyectos durante un año o así, así que me imagino que puede haber sido la fuente original! He editado el texto de modo que no parezca que estoy tratando de tomar el crédito para escribirlo ).
    • Cómo acerca de la decodificación de la codificación de caracteres?. Será normal proceso de decodificación usando NSUTF8StringEncoding dar a la cadena original?. ¿Alguien tiene idea de por que?.
    • Por qué? si (thisChar == ‘ ‘){ [salida appendString:@»+»]; } Con este si va a codificar los espacios con %20 como yo esperaría
    • kCFStringEncodingISOLatin1 es más común, pero de todos modos se debe establecer para la codificación configurado en el servidor web. (y sí CFURLCreateStringByAddingPercentEscapes es mejor en mi humilde opinión)
    • Esto es mucho más fácil en iOS 7. stackoverflow.com/a/20271177/31605
    • Respecto inclusiva vs exclusivo: vale la pena señalar que el RFC 3986 requiere codificación para sólo los caracteres reservados (es decir, un modelo inclusivo) y sólo en un contexto en el que fueron reservados. Por este motivo-no-codificación-todo enfoque probablemente ha causado más problemas de los que resuelve.
    • Codificar –> OK. Así que, ¿Cómo decodificar? 😀
    • ¿por qué se sustituye ‘{espacio}’ de ‘+’ en lugar de ‘%20’? Tuve que cambiarlo.
    • Sólo un 6-liner porque chown decidió colocar cada uno de los parámetros en una línea nueva. Y yo no tengo ningún problema con una categoría que se ajusta CFURLCreateStringByAddingPercentEscapes(), mi comentario fue escrito cuando chown sólo aparece el primer fragmento de código en su respuesta.
    • El de arriba no funciona. Es perturbado original de la obra así.
    • ¿Qué acerca de los caracteres rusos?
    • No funciona con distintos personajes (I. E en árabe, chino…) el primer carácter de unicode utf-8 secuencia codificada correcly desde > 127, pero los siguientes no lo son.
    • He estado recibiendo una advertencia, «la conversión implícita pierde enteros de precisión: unsigned long int» en sourceLen, que me he fijado por declarar sourceLen como NSUInteger.

  2. 125

    Esto puede ser de ayuda

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

    Para iOS 7+, la forma recomendada es:

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

    Usted puede elegir el conjunto de caracteres permitido como por la exigencia de la componente de URL.

    • NSUTF8StringEncoding es preferido en estos días..
    • Esto también no codificar correctamente el parámetro de delimitadores como ‘&’, ‘?’ en el caso de que se pasa el contenido a una API.
    • Esto no funciona. Esto no convertir & a %26.
    • ‘&’ no es un carácter válido para la URL parámetro de cadena de consulta. Por favor, trate de usar » &amp;’ en su lugar.
    • stringByAddingPercentEscapesUsingencoding es OBSOLETA «Uso -stringByAddingPercentEncodingWithAllowedCharacters: lugar, que siempre utiliza el recomendado la codificación UTF-8, y que codifica para una URL específica componente o subcomponente ya que cada URL componente o subcomponente tiene diferentes reglas para qué caracteres son válidos.»
  3. 89

    Nueva Api se han añadido ya que la respuesta fue seleccionado; Usted puede ahora utilizar NSURLUtilities. Desde diferentes partes de la Url de permitir que los diferentes caracteres, utilice el correspondiente conjunto de caracteres. En el ejemplo siguiente se codifica para la inclusión en la cadena de consulta:

    encodedString = [myString stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLQueryAllowedCharacterSet];

    Para convertir específicamente ‘&’, tendrás que eliminar de la url de la consulta o el conjunto de utilizar un conjunto diferente, como ‘&’ está permitido en una dirección URL de consulta:

    NSMutableCharacterSet *chars = NSCharacterSet.URLQueryAllowedCharacterSet.mutableCopy;
    [chars removeCharactersInRange:NSMakeRange('&', 1)]; //%26
    encodedString = [myString stringByAddingPercentEncodingWithAllowedCharacters:chars];
    • Me tomó un tiempo para averiguar lo que usted entiende por «uso NSURLUtilities» – pero ahora veo que es el nombre de la categoría de NSString en el que Apple se define este nuevo método en iOS 7 y OS X 10.9.
    • Hay algo más elaborado como una respuesta como esta aquí: stackoverflow.com/a/20271177/456366
    • Yup. Fue también en la lista de NSURLUtilities en el listado de la nueva Api de libertad.
    • Esto no funciona. Esto no convertir & a %26.
    • ‘&’ es, por supuesto, permite en una cadena de consulta, así que voy a editar mi respuesta usando Richard enlace.
    • NSMakeRange('&', 1) no funciona en Swift, ya que Swift no permite char a int conversión sin hacks. Para utilizar esta solución en el código Swift, uso removeCharactersInString("&") en lugar de .removeCharactersInRange(...)
    • obh2000, gracias. Esta cuestión ya está etiquetado objective-c, swift editar puede no ser apropiada. Siéntase libre de encontrar un swift versión o crear/responder a una nueva pregunta a ti mismo!

  4. 16

    Swift 2.0 Ejemplo (iOS 9 Compatiable)

    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
    
      }
    
    }
    • Es alucinante que esto es mucho esfuerzo…
    • parece que tienes que saltar a través de unos aros, para llegar hasta aquí, por eso es mejor ocultarla en una extensión de
    • para mí Int(String(Carácter(«&»))) devuelve nil, como debe ser. En lugar de los caracteres.removeCharactersInString(«&»).
  5. 14

    ios 7 actualización de

    NSString *encode = [string stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    
    NSString *decode = [encode stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    • Esto es impreciso. Usted querrá escapar de las diferentes partes de la URL de forma diferente. stackoverflow.com/questions/3423545/…
    • En realidad, depende de tu servidor de caracteres permitidos, aquí en mi ejemplo en el server yo lo estaba usando sólo se permite conjunto de caracteres alfanuméricos, usted puede cambiar los caracteres específicos para atender a sus necesidades.
    • La pregunta acerca de la codificación de la ‘&’ carácter.
  6. 8

    He optado por utilizar el CFURLCreateStringByAddingPercentEscapes llame como se da por aceptado respuesta, sin embargo, en la más reciente versión de XCode (IOS), que resultó en un error, por lo que se utiliza el siguiente lugar:

    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));
    • No es espacio de codificación. Ejemplo @»string» y @»string&string» está codificado correctamente. Por favor, hágamelo saber sus opiniones sobre el mismo.
    • para mí la mayor parte del tiempo resolviendo esta fue la negación período donde me negaba a creer que el marco no contienen algo de nombre similar a ‘urlencode’ que hace esto sin el cachondeo..
  7. 6

    Intentar utilizar stringByAddingPercentEncodingWithAllowedCharacters método con [NSCharacterSet URLUserAllowedCharacterSet] de cubrir todos los casos

    Objetivo C

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

    swift

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

    Salida

    Test%20%2F%20Test

    • Todavía no codifican &
  8. 6

    Después de leer todas las respuestas para este tema y la (mal) aceptado, quiero añadir mi contribución.

    SI el objetivo es iOS7+, y en 2017 se debe desde XCode hace realmente duro para ofrecer compatibilidad bajo iOS8, la mejor forma de hilo, seguro, rápido, amd con pleno soporte para UTF-8 para hacer esto es:

    (Objetivo C código)

    @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

    Esto extenderá NSString, excluirá RFC caracteres prohibidos, soporte de caracteres UTF-8, y dejar de usar cosas como:

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

    Que va a imprimir en la consola de depuración:

    Fuente: soy el[mal]&quiere(a)descanso!!!$->àéìòù -> Dest: I%27m%5Bevil%5D%26want%28to%29break%21%21%21%24-%3E%C3%A0%C3%A9%C3%AC%C3%B2%C3%B9

    … tenga en cuenta también el uso de dispatch_once para evitar múltiples inicializaciones en entornos multiproceso.

  9. 4

    código swift basado en chown‘s objc respuesta en este hilo.

    extension String {
        func urlEncode() -> String {
            return CFURLCreateStringByAddingPercentEscapes(
                nil,
                self,
                nil,
                "!*'();:@&=+$,/?%#[]",
                CFStringBuiltInEncodings.UTF8.rawValue
            )
        }
    }
    • esta función ya no se utiliza en iOS 9 🙁
  10. 4

    Uso NSURLComponents para codificar HTTP GET parámetros:

        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/

    • La única respuesta correcta para iOS 8 y superior (:
    • No codificar el signo, barras o puntos y comas.
  11. 4

    Aquí está una lista para producción de enfoque flexible en 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())
        }
    }

    Ejemplo de uso:

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

    De salida:

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

    Este código me ayudó para la codificación de caracteres especiales

    NSString* encPassword = [password stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet alphanumericCharacterSet]];
  13. 2

    En Swift 3, por favor, pruebe a continuación:

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

    Ya que, stringByAddingPercentEscapesUsingEncoding no codifica URL personajes, pero las hojas de los caracteres reservados (como !*'();:@&=+$,/?%#[]), Usted puede codificar la url como el código siguiente:

    let stringURL = "YOUR URL TO BE ENCODE";
    let characterSetTobeAllowed = (CharacterSet(charactersIn: "!*'();:@&=+$,/?%#[] ").inverted)
    if let encodedURLString = stringURL.addingPercentEncoding(withAllowedCharacters: characterSetTobeAllowed) {
        print(encodedURLString)
    }
  14. 2

    En swift 3:

    //exclude alpha and numeric == "full" encoding
    stringUrl = stringUrl.addingPercentEncoding(withAllowedCharacters: .alphanumerics)!;
    
    //exclude hostname and symbols &,/and etc
    stringUrl = stringUrl.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!;
  15. 2

    De Apple asesoramiento, en el 10.11 notas de la versión, es:

    Si usted necesita por ciento-codificar toda una cadena de dirección URL, puede utilizar este código para codificar un NSString la intención de ser una dirección URL (en urlStringToEncode):

    NSString *percentEncodedURLString =
      [[NSURL URLWithDataRepresentation:[urlStringToEncode dataUsingEncoding:NSUTF8StringEncoding] relativeToURL:nil] relativeString];
    • parece que no funciona, caracteres como & todavía quedan solos
  16. 1

    En mi caso, donde el último componente fue de las letras árabes hice lo siguiente en 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;
    }
    }

    uso:

    let stringURL = "http://xxx.dev.com/endpoint/nonLatinCharacters"
    
    if let encodedStringURL = stringURL.encodeUTF8() {
    
        if let url = NSURL(string: encodedStringURL) {
    
          ...
        }
    
    } 
  17. 1
    -(NSString *)encodeUrlString:(NSString *)string {
      return CFBridgingRelease(
                        CFURLCreateStringByAddingPercentEscapes(
                            kCFAllocatorDefault,
                            (__bridge CFStringRef)string,
                            NULL,
                            CFSTR("!*'();:@&=+$,/?%#[]"),
                            kCFStringEncodingUTF8)
                        );
    }

    según el siguiente blog

  18. 0

    Individuales www forma codificada en los parámetros de la consulta, hice una categoría en la NSString:

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

    //Este es sin prueba

    NSMutableCharacterSet* set = [[NSCharacterSet alphanumericCharacterSet] mutableCopy];
    [set addCharactersInString:@"-_.~"];
    NSString *encode = [test stringByAddingPercentEncodingWithAllowedCharacters:set];
    • Por qué? No debería ser difícil para ejecutar su propio código.
  20. 0

    Me enfrenté a un problema similar pasar cadenas complejas como un parámetro POST. Mis cadenas pueden contener caracteres Asiáticos, espacios, comillas y todo tipo de caracteres especiales. La solución final encontré fue la de convertir la cadena en la coincidencia de una serie de unicodes, por ejemplo, «Hu0040Hu0020Hu03f5….» el uso de [NSString stringWithFormat:@»Hu%04x»,[string characterAtIndex:i]] para obtener el Unicode de cada carácter en la cadena original. Lo mismo se puede hacer en Java.

    Esta cadena puede ser de forma segura que se pasa como parámetro POST.

    En el lado del servidor (PHP), puedo cambiar todo de la «H» a «\» y me pase la cadena resultante a json_decode. El paso Final es escapar las comillas simples antes de almacenar la cadena de caracteres en MySQL.

    De esta forma, se puede almacenar cualquier UTF8 string en mi servidor.

  21. 0

    Este es trabajo para mí.

    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
    }

    He encontrado la función anterior de este enlace: http://useyourloaf.com/blog/how-to-percent-encode-a-url-string/

    También puede utilizar esta función con swift extensión. Por favor, hágamelo saber si hay algún problema.

Dejar respuesta

Please enter your comment!
Please enter your name here