Reputation: 2000
I'm trying to decode a json request using Alamofire 5.2 The problem is that I use JSONDecoder and I have some issues about the conversion
The API is in Spanish and my models in English so I decided to changed this kind of values using an enum of keys
But I don't know if this works... Here's my code:
API RESPONSE: (json variable)
{
"sistemaOperativoId" : 0,
"nombreUsuario" : "Coasnf_09",
"menus" : [
],
"acciones" : [
],
"fechaRegistro" : "2020-04-15T09:46:24.0573154",
"empresa" : null,
"version" : null
}
MY MODEL:
struct UserP: Decodable{
var username : String
var company : String
private enum CodingKeys: String, CodingKey{
case username = "nombreUsuario"
case company = "empresa"
}
init(from decoder: Decoder) throws{
let container = try decoder.container(keyedBy: CodingKeys.self)
username = try container.decode(String.self, forKey: .username) ?? "null"
company = try container.decode(String.self, forKey: .company) ?? "null"
}
init(username: String, company: String){
self.username = username
self.company = company
}
}
CONVERTION:
func login(user: User) -> UserP? {
var userData: UserP! = nil
AF.request(UserRouter.login(user: user)).responseJSON{ response in
switch response.result {
case .success(let response):
print(response)
let dict = (response as? [String : Any])!
let json = dict["data"] as! [String: Any]
if let jsonData = try? JSONSerialization.data(withJSONObject: json , options: .prettyPrinted)
{
do {
var jsonString = String(data: jsonData, encoding: String.Encoding.utf8)!
print(jsonString)
userData = try JSONDecoder().decode(UserP.self, from: Data(jsonString.utf8))
print("Object Converted: ", userData.username)
} catch {
print("Parsing Failed: ", error.localizedDescription)
}
}
break
case .failure(let error):
print(error)
break
}
}
return userData
}
Upvotes: 1
Views: 493
Reputation: 20234
response
from Alamofire
has a data
property that you can use directly:
let json = response.data
do {
let user = try JSONDecoder().decode(UserP.self, from: json)
print(user)
}
catch {
print(error)
}
Furthermoe, if the keys nombreUsuario
and empresa
are not guaranteed to come in the json then recommended way is to mark those variables as optional. With this you don't need the custom decoder logic.
struct UserP: Decodable {
var username: String?
var company: String?
private enum CodingKeys: String, CodingKey{
case username = "nombreUsuario"
case company = "empresa"
}
}
If you want to give some default values then a custom decoder can help:
struct UserP: Decodable {
var username: String
var company: String
private enum CodingKeys: String, CodingKey{
case username = "nombreUsuario"
case company = "empresa"
}
init(from decoder: Decoder) throws{
let container = try decoder.container(keyedBy: CodingKeys.self)
username = try container.decodeIfPresent(String.self, forKey: .username) ?? "Default Name"
company = try container.decodeIfPresent(String.self, forKey: .company) ?? "Default Company Name"
}
}
Upvotes: 1