Swift 2.1
Un trazador de líneas:
"p1=v1&p2=v2".componentsSeparatedByString("&").map {
$0.componentsSeparatedByString("=")
}.reduce([:]) {
(var dict: [String:String], p) in
dict[p[0]] = p[1]
return dict
}
Usado como una extensión en NSURL:
extension NSURL {
public var queryValues : [String:String] {
get {
if let q = self.query {
return q.componentsSeparatedByString("&").map {
$0.componentsSeparatedByString("=")
}.reduce([:]) {
(var dict: [String:String], p) in
dict[p[0]] = p[1]
return dict
}
} else {
return [:]
}
}
}
}
Ejemplo:
let url = NSURL(string: "http://example.com?p1=v1&p2=v2")!
let queryDict = url.queryValues
Tenga en cuenta que si usa OS X 10.10 o iOS 8 (o posterior), probablemente sea mejor usar NSURLComponents
y la queryItems
propiedad y crear el diccionario NSURLQueryItems
directamente desde.
Aquí hay una solución de extensión NSURLComponents
basada NSURL
:
extension NSURL {
public var queryValues : [String:String] {
get {
guard let components = NSURLComponents(URL: self, resolvingAgainstBaseURL: false) else {
return [:]
}
guard let queryItems = components.queryItems else {
return [:]
}
var result:[String:String] = [:]
for q in queryItems {
result[q.name] = q.value
}
return result
}
}
}
Una nota al pie de la extensión NSURL es que en realidad es posible en Swift darle a la propiedad el mismo nombre que la propiedad de cadena existente— query
. No lo supe hasta que lo probé, pero el polimorfismo en Swift te permite diferenciar solo en el tipo de retorno. Entonces, si la propiedad NSURL extendida es public var query: [String:String]
, funciona. No utilicé esto en el ejemplo porque lo encuentro un poco loco, pero funciona ...