Swift Codable init

后端 未结 2 1635
一整个雨季
一整个雨季 2021-02-08 11:13

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 
           


        
相关标签:
2条回答
  • 2021-02-08 12:03

    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.

    0 讨论(0)
  • 2021-02-08 12:07

    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)
    
    0 讨论(0)
提交回复
热议问题