Swift - codificar URL

Resuelto MegaCookie asked hace 54 años • 21 respuestas

Si codifico una cadena como esta:

var escapedString = originalString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)

no escapa a las barras /.

Busqué y encontré este código Objective C:

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

¿Existe una forma más sencilla de codificar una URL y, de no ser así, cómo escribo esto en Swift?

MegaCookie avatar Jan 01 '70 08:01 MegaCookie
Aceptado

veloz 3

En Swift 3 hayaddingPercentEncoding

let originalString = "test/test"
let escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
print(escapedString!)

Producción:

prueba%2Fprueba

veloz 1

En iOS 7 y superior haystringByAddingPercentEncodingWithAllowedCharacters

var originalString = "test/test"
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())
println("escapedString: \(escapedString)")

Producción:

prueba%2Fprueba

Los siguientes son conjuntos de caracteres útiles (invertidos):

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

Si desea que se escape un conjunto diferente de caracteres, cree un conjunto:
Ejemplo con el carácter "=" agregado:

var originalString = "test/test=42"
var customAllowedSet =  NSCharacterSet(charactersInString:"=\"#%/<>?@\\^`{|}").invertedSet
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(customAllowedSet)
println("escapedString: \(escapedString)")

Producción:

prueba%2Fprueba%3D42

Ejemplo para verificar caracteres ascii que no están en el conjunto:

func printCharactersInSet(set: NSCharacterSet) {
    var characters = ""
    let iSet = set.invertedSet
    for i: UInt32 in 32..<127 {
        let c = Character(UnicodeScalar(i))
        if iSet.longCharacterIsMember(i) {
            characters = characters + String(c)
        }
    }
    print("characters not in set: \'\(characters)\'")
}
zaph avatar Jul 03 '2014 11:07 zaph

Puede utilizar URLComponents para evitar tener que cifrar manualmente el porcentaje de su cadena de consulta:

let scheme = "https"
let host = "www.google.com"
let path = "/search"
let queryItem = URLQueryItem(name: "q", value: "Formula One")


var urlComponents = URLComponents()
urlComponents.scheme = scheme
urlComponents.host = host
urlComponents.path = path
urlComponents.queryItems = [queryItem]

if let url = urlComponents.url {
    print(url)   // "https://www.google.com/search?q=Formula%20One"
}

extension URLComponents {
    init(scheme: String = "https",
         host: String = "www.google.com",
         path: String = "/search",
         queryItems: [URLQueryItem]) {
        self.init()
        self.scheme = scheme
        self.host = host
        self.path = path
        self.queryItems = queryItems
    }
}

let query = "Formula One"
if let url = URLComponents(queryItems: [URLQueryItem(name: "q", value: query)]).url {
    print(url)  // https://www.google.com/search?q=Formula%20One
}
Leo Dabus avatar Apr 27 '2017 21:04 Leo Dabus

Rápido 4 y 5

Para codificar un parámetro en una URL, creo que usar .alphanumericsel juego de caracteres es la opción más sencilla:

let urlEncoded = value.addingPercentEncoding(withAllowedCharacters: .alphanumerics)
let url = "http://www.example.com/?name=\(urlEncoded!)"

El uso de cualquiera de los conjuntos de caracteres estándar para la codificación de URL (como .urlQueryAllowedo .urlHostAllowed) no funcionará porque no excluyen =caracteres &.

El uso URLComponentstampoco funciona correctamente porque no escapa al +personaje.

Tenga en cuenta que al usarlo .alphanumericsse codificarán algunos caracteres que no es necesario codificar (como -, o -– consulte 2.3. Caracteres no reservados en RFC 3986). Considero que usar es más simple que construir un conjunto de caracteres personalizado y no me importa codificar algunos caracteres adicionales. Si eso le molesta, cree un conjunto de caracteres personalizado como se describe en Cómo codificar por ciento una cadena URL , como por ejemplo:._~.alphanumerics

// Store allowed character set for reuse (computed lazily).
private let urlAllowed: CharacterSet =
    .alphanumerics.union(.init(charactersIn: "-._~")) // as per RFC 3986

extension String {
    var urlEncoded: String? {
        return addingPercentEncoding(withAllowedCharacters: urlAllowed)
    }
}

let url = "http://www.example.com/?name=\(value.urlEncoded!)"

Advertencia: El urlEncodedparámetro se desencapsula a la fuerza. Para una cadena Unicode no válida, podría fallar. Consulte ¿ Por qué el valor de retorno de String.addingPercentEncoding() es opcional? . En lugar de forzar el desenvolvimiento, urlEncoded!puedes usar urlEncoded ?? ""o if let urlEncoded = urlEncoded { ... }.

Marián Černý avatar Mar 12 '2018 08:03 Marián Černý

Rápido 5:

extension String {
    var urlEncoded: String? {
        let allowedCharacterSet = CharacterSet.alphanumerics.union(CharacterSet(charactersIn: "~-_."))
        return self.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet)
    }
}

print("\u{48}ello\u{9}world\u{7}\u{0}".urlEncoded!) // prints Hello%09world%07%00
print("The string ü@foo-bar".urlEncoded!) // prints The%20string%20%C3%BC%40foo-bar


Hong Wei avatar Sep 29 '2016 10:09 Hong Wei