I've been experimenting with customized Decodable properties for handling JSON in Swift 4 and I'm really impressed with the ease of mapping tricky type and format conversions.
However in the JSON data structures that the server exposes to me, only a handful of properties need this treatment. The rest are simple integers and strings. Is there some way to mix the customized decoder with the standard one?
Here's a simplified example showing what I'd like to get rid of:
struct mystruct : Decodable {
var myBool: Bool
var myDecimal: Decimal
var myDate: Date
var myString: String
var myInt: Int
}
extension mystruct {
private struct JSONsource: Decodable {
var my_Bool: Int
var my_Decimal: String
var my_Date: String
// These seem redundant, how can I remove them?
var myString: String
var myInt: Int
}
private enum CodingKeys: String, CodingKey {
case item
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let item = try container.decode(JSONsource.self, forKey: .item)
myBool = item.my_Bool == 1 ? true : false
myDecimal = Decimal(string: item.my_Decimal)!
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSSZZZZZ"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
myDate = dateFormatter.date(from: item.my_Date)!
// Can I somehow get rid of this redundant-looking code?
myString = item.myString
myInt = item.myInt
}
}
let myJSON = """
{
"item": {
"my_Decimal": "123.456",
"my_Bool" : 1,
"my_Date" : "2019-02-08T11:14:31.4547774-05:00",
"myInt" : 148727,
"myString" : "Hello there!"
}
}
""".data(using: .utf8)
let x = try JSONDecoder().decode(mystruct.self, from: myJSON!)
print("My decimal: \(x.myDecimal)")
print("My bool: \(x.myBool)")
print("My date: \(x.myDate)")
print("My int: \(x.myInt)")
print("My string: \(x.myString)")