Cómo usar stringByAddingPercentEncodingWithAllowedCharacters() para una URL en Swift 2.0
swift2 nscharacterset (6)
Estaba usando esto, en Swift 1.2
let urlwithPercentEscapes = myurlstring.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
Esto ahora me da una advertencia pidiéndome que use
stringByAddingPercentEncodingWithAllowedCharacters
Necesito usar un NSCharacterSet como argumento, pero hay tantos y no puedo determinar cuál me dará el mismo resultado que el método utilizado anteriormente.
Un ejemplo de URL que quiero usar será así
http://www.mapquestapi.com/geocoding/v1/batch?key=YOUR_KEY_HERE&callback=renderBatch&location=Pottsville,PA&location=Red Lion&location=19036&location=1090 N Charlotte St, Lancaster, PA
El conjunto de caracteres de URL para la codificación parece contener conjuntos que recortan mi URL. es decir,
El componente de ruta de una URL es el componente que sigue inmediatamente al componente host (si está presente). Finaliza donde comienza el componente de consulta o fragmento. Por ejemplo, en la URL http://www.example.com/index.php?key1=value1 , el componente de ruta es /index.php.
Sin embargo, no quiero recortar ningún aspecto.
Cuando usaba mi String, por ejemplo,
myurlstring
.
Pero cuando se usa lo siguiente, entonces no hubo problemas. Codificó la cadena con algo de magia y pude obtener mis datos de URL.
let urlwithPercentEscapes = myurlstring.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
Como lo
Devuelve una representación de la cadena utilizando una codificación dada para determinar los porcentajes de escape necesarios para convertir la cadena en una cadena de URL legal
Gracias
Dependerá de tu url. Si su url es una ruta, puede usar el juego de caracteres urlPathAllowed
let myFileString = "My File.txt"
if let urlwithPercentEscapes = myFileString.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) {
print(urlwithPercentEscapes) // "My%20File.txt"
}
Crear un juego de caracteres para la codificación de URL
urlFragmentAllowed
urlHostAllowed
urlPasswordAllowed
urlQueryAllowed
urlUserAllowed
También puede crear su propio conjunto de caracteres de URL:
let myUrlString = "http://www.mapquestapi.com/geocoding/v1/batch?key=YOUR_KEY_HERE&callback=renderBatch&location=Pottsville,PA&location=Red Lion&location=19036&location=1090 N Charlotte St, Lancaster, PA"
let urlSet = CharacterSet.urlFragmentAllowed
.union(.urlHostAllowed)
.union(.urlPasswordAllowed)
.union(.urlQueryAllowed)
.union(.urlUserAllowed)
extension CharacterSet {
static let urlAllowed = CharacterSet.urlFragmentAllowed
.union(.urlHostAllowed)
.union(.urlPasswordAllowed)
.union(.urlQueryAllowed)
.union(.urlUserAllowed)
}
if let urlwithPercentEscapes = myUrlString.addingPercentEncoding(withAllowedCharacters: .urlAllowed) {
print(urlwithPercentEscapes) // "http://www.mapquestapi.com/geocoding/v1/batch?key=YOUR_KEY_HERE&callback=renderBatch&location=Pottsville,PA&location=Red%20Lion&location=19036&location=1090%20N%20Charlotte%20St,%20Lancaster,%20PA"
}
Otra opción es usar URLComponents para crear correctamente su url
En Swift 3.1, estoy usando algo como lo siguiente:
let query = "param1=value1¶m2=" + valueToEncode.addingPercentEncoding(withAllowedCharacters: .alphanumeric)
Es más seguro que .urlQueryAllowed y los demás, ya que esto codificará todos los caracteres que no sean AZ, az y 0-9. Esto funciona mejor cuando el valor que está codificando puede usar caracteres especiales como?, &, =, + Y espacios.
En mi caso donde el último componente eran caracteres no latinos, 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;
}
}
Para la cadena de URL dada, el equivalente a
let urlwithPercentEscapes = myurlstring.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
es el conjunto de caracteres
URLQueryAllowedCharacterSet
let urlwithPercentEscapes = myurlstring.stringByAddingPercentEncodingWithAllowedCharacters( NSCharacterSet.URLQueryAllowedCharacterSet())
Swift 3:
let urlwithPercentEscapes = myurlstring.addingPercentEncoding( withAllowedCharacters: .urlQueryAllowed)
Codifica todo después del signo de interrogación en la cadena URL.
Dado que el método
stringByAddingPercentEncodingWithAllowedCharacters
puede devolver nil, use enlaces opcionales como se sugiere en la respuesta de Leo Dabus.
Swift 3.0 (desde grokswift )
Crear URL a partir de cadenas es un campo minado para errores.
Simplemente pierda una URL simple o accidentalmente codifique el?
en una consulta y su llamada a la API fallará y su aplicación no tendrá datos para mostrar (o incluso bloquearse si no anticipó esa posibilidad).
Desde iOS 8 hay una mejor manera de construir URL usando
NSURLComponents
y
NSURLQueryItems
.
func createURLWithComponents() -> URL? {
var urlComponents = URLComponents()
urlComponents.scheme = "http"
urlComponents.host = "www.mapquestapi.com"
urlComponents.path = "/geocoding/v1/batch"
let key = URLQueryItem(name: "key", value: "YOUR_KEY_HERE")
let callback = URLQueryItem(name: "callback", value: "renderBatch")
let locationA = URLQueryItem(name: "location", value: "Pottsville,PA")
let locationB = URLQueryItem(name: "location", value: "Red Lion")
let locationC = URLQueryItem(name: "location", value: "19036")
let locationD = URLQueryItem(name: "location", value: "1090 N Charlotte St, Lancaster, PA")
urlComponents.queryItems = [key, callback, locationA, locationB, locationC, locationD]
return urlComponents.url
}
A continuación se muestra el código para acceder a la URL utilizando la declaración de
guard
.
guard let url = createURLWithComponents() else {
print("invalid URL")
return nil
}
print(url)
Salida:
http://www.mapquestapi.com/geocoding/v1/batch?key=YOUR_KEY_HERE&callback=renderBatch&location=Pottsville,PA&location=Red%20Lion&location=19036&location=1090%20N%20Charlotte%20St,%20Lancaster,%20PA
Swift 4.0
let encodedData = myUrlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlHostAllowed)