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 NSURLComponentsy la queryItemspropiedad y crear el diccionario NSURLQueryItemsdirectamente desde.
Aquí hay una solución de extensión NSURLComponentsbasada 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 ...