Я могу сделать успешный POST-запрос в POSTMAN следующим образом:
{
"id": "1",
"myDictKey": {
"key0": "blah",
"key1": "blah",
"key2": "blah"
}
}
Однако, когда я пытаюсь сделать этот POST-запрос в быстром, POST не выполняется. Кажется, что параметр NSDictionary не кодируется должным образом.
Swift Code
let dictParam = ["key0": "blah", "key1": "blah", "key2": "blah"] as NSDictionary
let urlString = MY_URL
let url = URL(string: urlString)!
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let parameters: [String: Any] = [
"id": "1",
"myDictKey": dictParam
]
request.httpBody = parameters.percentEncoded()
let task = URLSession.shared.dataTask(with: request) { data, response, error -> Void in
if error != nil {
completion(nil, error?.localizedDescription)
return
}
do {
if let json = try JSONSerialization.jsonObject(with: data!, options: [.allowFragments]) as? NSDictionary {
if response?.statusCode() == 200 {
if let jsonResponse = json.value(forKeyPath: "response") as? NSDictionary {
completion(jsonResponse, nil)
return
} else if response?.statusCode() == 401 {
completion(nil, "Unauthorized")
} else {
completion(nil, "Something went wrong. Try again later")
}
}
} catch {
completion(nil, "Something went wrong. Try again later")
}
}
task.resume()
процентEncoded ()
// MARK: - Dictionary
extension Dictionary {
func percentEncoded() -> Data? {
return map { key, value in
let escapedKey = "\(key)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
let escapedValue = "\(value)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
return escapedKey + "=" + escapedValue
}
.joined(separator: "&")
.data(using: .utf8)
}
}
Набор символов
// MARK: - CharacterSet
extension CharacterSet {
static let urlQueryValueAllowed: CharacterSet = {
let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4
let subDelimitersToEncode = "!$&'()*+,;="
var allowed = CharacterSet.urlQueryAllowed
allowed.remove(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)")
return allowed
}()
}