Reputation: 3464
I have created a model as per below with one custom enum for gender
enum Gender :String, Codable {
case male = "Male"
case female = "Female"
}
class Person : Codable {
var name : String?
var gender : Gender?
convenience init(name : String, gender : Gender) {
self.init()
self.name = name
self.gender = gender
}
enum CodingKeys: String, CodingKey {
case name = "name"
case gender = "gender"
}
}
Below is my json data from the API
[
{
"name": "name1",
"gender": "Male"
},
{
"name": "name2",
"gender": "Male"
}
]
in the success block of response if I am parsing data with below code it is working fine
do {
let list = try JSONDecoder().decode([Person].self, from: data)
print("list \(list)")
}
catch {
print("error \(error)")
}
Now Problem is when in the response api if gender is provided in all lower case like "gender": "male"
then the parsing is not working and give below error.
error dataCorrupted(Swift.DecodingError.Context(codingPath:
[_JSONKey(stringValue: "Index 1", intValue: 1), CodingKeys(stringValue:
"gender", intValue: nil)], debugDescription: "Cannot initialize Gender from
invalid String value male", underlyingError: nil))
I want any one solution from below
One more thing I don't want to override encoder and decoder method as I have many parameter in my actual project. I am already aware of that.
Upvotes: 3
Views: 678
Reputation: 53131
You can do this by overriding the init(from decoder:)
for Person
…
enum Gender :String, Codable {
case male, female // Note that I removed the uppercase string values
}
struct Person : Codable {
var name : String?
var gender : Gender?
enum CodingKeys: String, CodingKey {
case name, gender // No need for string values if they match the enum cases
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decodeIfPresent(String.self, forKey: .name) // decodeIfPresent as name is optional
let genderString = try container.decode(String.self, forKey: .gender)
gender = Gender(rawValue: genderString.lowercased()) // This is why I removed the uppercase String values
}
}
Upvotes: 2