Skip to content

Instantly share code, notes, and snippets.

@kyungpyoda
Created May 28, 2021 01:17
Show Gist options
  • Save kyungpyoda/2e914ea8c417e095672c90482bc973de to your computer and use it in GitHub Desktop.
Save kyungpyoda/2e914ea8c417e095672c90482bc973de to your computer and use it in GitHub Desktop.
[Swift] Codable class and inheritance
//
// CodableInheritanceExample.swift
//
// Created by 홍경표 on 2021/05/28.
//
class BaseResponse: Codable {
var retCode: Int = 0
private enum CodingKeys: String, CodingKey {
case retCode
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
retCode = try container.decode(Int.self, forKey: .retCode)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(retCode, forKey: .retCode)
}
}
final class SpecialResponse: BaseResponse {
var temp: Int?
var message: String?
private enum CodingKeys: String, CodingKey {
case temp
case message
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
try super.init(from: decoder)
temp = try? container.decode(Int?.self, forKey: .temp)
message = try? container.decode(String?.self, forKey: .message)
}
override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try super.encode(to: encoder)
try? container.encode(temp, forKey: .temp)
try? container.encode(message, forKey: .message)
}
}
// !! Need to use `try?`, not `try` at 39, 40 lines. !!
//
// Because `temp` and `message` are optional, so you don't know if they exist or not.
// If there is no `message`(or `temp) and if you use `try`(not `try?`)
// ,then the decoder will recognize `message` as `Int with nil`.
// and you will get this error message.
/*
DecodingError
▿ keyNotFound : 2 elements
- .0 : CodingKeys(stringValue: "message", intValue: nil)
▿ .1 : Context
- codingPath : 0 elements
- debugDescription : "No value associated with key CodingKeys(stringValue: \"message\", intValue: nil) (\"message\")."
- underlyingError : nil
*/
/*
let encoder = JSONEncoder()
let decoder = JSONDecoder()
let dict: [String: Int] = ["retCode": 1, "temp": 1000]
let data = try encoder.encode(dict)
debugPrint(String(data: data, encoding: .utf8) as Any)
let decoded = try decoder.decode(SpecialResponse.self, from: data)
dump(decoded)
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment