I would like to do some initialization logic after the Swift Coding/Encoding feature has finished decoding a JSON.
struct MyStruct: Codable {
let id: Int
Either you get everything for free but standardized or you have to write a custom initializer like
struct MyStruct: Codable {
let id: Int
var name: String
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(Int.self, forKey: .id)
let decodedName = try container.decode(String.self, forKey: .name)
name = "\(id) \(decodedName)"
}
}
You can implement init()
but this works independent of the decoding functionality and you have to assign a default value to all non-optional properties, that's what the error says.
Use a factory method that first uses init(from:)
and then calls your custom initialization code
struct Foo: Decodable {
let name: String
let id: Int
var x: String!
private mutating func finalizeInit() {
self.x = "\(name) \(id)"
}
static func createFromJSON(_ data: Data) -> Foo? {
guard var f = try? JSONDecoder().decode(Foo.self, from: data) else {
return nil
}
f.finalizeInit()
return f
}
}
let sampleData = """
{ "name": "foo", "id": 42 }
""".data(using: .utf8)!
let f = Foo.createFromJSON(sampleData)