Beim Erstellen einer GETAnfrage gibt es keinen Textkörper für die Anfrage, sondern alles geht über die URL. Sie können auch eine URL erstellen (und den Prozentsatz, der ihr entgeht) URLComponents.
var url = URLComponents(string: "https://www.google.com/search/")!
url.queryItems = [
URLQueryItem(name: "q", value: "War & Peace")
]
Der einzige Trick besteht darin, dass für die meisten Webdienste ein +prozentualer Escapezeichen erforderlich ist (da dies als Leerzeichen gemäß der application/x-www-form-urlencodedSpezifikation interpretiert wird ). Aber URLComponentswird nicht Prozent davon entkommen. Apple behauptet, dass dies +ein gültiges Zeichen in einer Abfrage ist und daher nicht maskiert werden sollte. Technisch gesehen sind sie richtig, dass es in einer Abfrage eines URI erlaubt ist, aber es hat eine besondere Bedeutung in application/x-www-form-urlencodedAnfragen und sollte wirklich nicht ohne Flucht übergeben werden.
Apple räumt ein, dass wir den +Zeichen prozentual entkommen müssen , rät jedoch, dies manuell zu tun:
var url = URLComponents(string: "https://www.wolframalpha.com/input/")!
url.queryItems = [
URLQueryItem(name: "i", value: "1+2")
]
url.percentEncodedQuery = url.percentEncodedQuery?.replacingOccurrences(of: "+", with: "%2B")
Dies ist eine unelegante Problemumgehung, die jedoch funktioniert. Apple empfiehlt, wenn Ihre Abfragen möglicherweise ein +Zeichen enthalten und Sie einen Server haben, der sie als Leerzeichen interpretiert.
Wenn Sie das mit Ihrer sendRequestRoutine kombinieren , erhalten Sie so etwas wie:
func sendRequest(_ url: String, parameters: [String: String], completion: @escaping ([String: Any]?, Error?) -> Void) {
var components = URLComponents(string: url)!
components.queryItems = parameters.map { (key, value) in
URLQueryItem(name: key, value: value)
}
components.percentEncodedQuery = components.percentEncodedQuery?.replacingOccurrences(of: "+", with: "%2B")
let request = URLRequest(url: components.url!)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data,
let response = response as? HTTPURLResponse,
(200 ..< 300) ~= response.statusCode,
error == nil else {
completion(nil, error)
return
}
let responseObject = (try? JSONSerialization.jsonObject(with: data)) as? [String: Any]
completion(responseObject, nil)
}
task.resume()
}
Und du würdest es so nennen:
sendRequest("someurl", parameters: ["foo": "bar"]) { responseObject, error in
guard let responseObject = responseObject, error == nil else {
print(error ?? "Unknown error")
return
}
}
Persönlich würde ich JSONDecoderheutzutage verwenden und einen benutzerdefinierten structanstelle eines Wörterbuchs zurückgeben, aber das ist hier nicht wirklich relevant. Hoffentlich veranschaulicht dies die Grundidee, wie die Parameter in die URL einer GET-Anforderung prozentual codiert werden.
Siehe vorherige Überarbeitung dieser Antwort für Swift 2 und manuelle prozentuale Fluchtversuche.
extension stringmit den Werten macht? Auch wann müsste ichHttpBodydann verwenden?