I'm trying to parse data from the server, but I get this error:
failure(Swift.DecodingError.typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary<String, Any> but found an array instead.", underlyingError: nil)))
The parameters should be passed as an array of objects, as well as the response object. I can't figure out what should I change in my code so the response is well structured. This is what a response looks like:
[
{
'code' : number,
'error' => boolean,
'code_error' => number,
'data_error' => string,
'message' => 'Falta Campo requerido'
}
]
These are the parameters that should be passed:
[
{
'email' => 'required|string|email',
'event_type' => 'required|string',
'watermark' => 'required|string',
'date' => 'required',
'location' => 'required|string',
'segment' => 'required',
'time' => 'required',
'country' => 'required',
'city' => 'required'
}
]
And this is what my code looks like.
Data:
struct MarcaAguaResData: Codable {
let code: Int
let error: Bool
let message: String
}
struct MarcaAguaErrorResponse: Decodable, LocalizedError {
let code: Int
let error: Bool
let message: String
let code_error: Int
let data_error: String
}
Server:
class MarcaAguaService {
func marcaAgua(parameters: [String: Any],
completion: @escaping (Result<MarcaAguaResData, Error>)-> Void) {
let urlString = baseUrl + "events"
guard let url = URL(string: urlString) else {
completion(.failure(NetworkingError.badUrl))
return
}
var request = URLRequest(url: url)
var components = URLComponents()
var queryItems = [URLQueryItem]()
for (key, value) in parameters {
let queryItem = URLQueryItem(name: key, value: String(describing: value))
queryItems.append(queryItem)
}
components.queryItems = queryItems
let queryItemsData = components.query?.data(using: .utf8)
request.httpBody = queryItemsData
request.httpMethod = "POST"
request.setValue("Bearer \(token_login)", forHTTPHeaderField: "Authorization")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let session = URLSession.shared
let task = session.dataTask(with: request) { (data, response, error) in
DispatchQueue.main.async {
guard let unwrappedResponse = response as? HTTPURLResponse else {
completion(.failure(NetworkingError.badResponse))
return
}
switch unwrappedResponse.statusCode {
case 200 ..< 300:
print("success")
default:
print("failure")
}
if let unwrappedError = error {
completion(.failure(unwrappedError))
return
}
if let unwrappedData = data {
do{
let json = try JSONSerialization.jsonObject(with: unwrappedData, options: .allowFragments)
print("BBBB")
print(json)
if let successRes = try? JSONDecoder().decode(MarcaAguaResData.self, from: unwrappedData){
completion(.success(successRes))
}else{
let errorResponse = try JSONDecoder().decode(MarcaAguaErrorResponse.self, from: unwrappedData)
print("Error \(errorResponse)")
completion(.failure(errorResponse))
}
}catch{
print("AAA")
completion(.failure(error))
}
}
}
}
task.resume()
}
}
decode(CodableStruct.self,means you expect an objectCodableStructat top level of your JSON.decode([CodableStruct].self,means you expect an array ofCodableStructat top level of your JSON. You are sending an array, so you aren't decoding correctly...queryItemsDatawhich is in form or url encoded data, and not JSON? It's strange, since you receive JSON, and you put in content-type, JSON...request.httpBody = try? JSONSerialization.data(withJSONObject: parameters)orrequest.httpBody = try? JSONSerialization.data(withJSONObject: [parameters])(it's unclear if you send only one or an array of objects). For your decoding fix,MarcaAguaErrorResponse.self-> [MarcaAguaErrorResponse].self` Might be the same diff in success:MarcaAguaResData.self=>[MarcaAguaResData].self