- Published on
๐ Swift - Decoder์ Container
- Authors
- Name
- ์ด์ฐฝ์ค
- ๋ฐฐ๊ฒฝ
- ๊ณผ์
- Container
- KeyedDecodingContainer
- SingleValueContainer
- UnkeyedContainer
- ์๋ฌ ํด๊ฒฐ
- ๊ฒฐ๊ณผ
- ์ฐธ๊ณ ๋ฌธ์
๋ฐฐ๊ฒฝ
- ๋ญ๋ง ํ๋ฉด ๋์ฝ๋ฉ ์๋ฌ!
- ๋๋ฌด ์๋ฏผ๋ณด์ค์ธ
Encodable
๊ณผDecodable
- ๋๋ฌด ์๋ฏผ๋ณด์ค์ธ
๊ณผ์
์ด๋ฒ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉฐ ์์์น ๋ชป ํ ์ธ์ฝ๋ฉ/๋์ฝ๋ฉ ์๋ฌ๋ค์ ๋ง์ฃผ์ณค์ต๋๋ค.
์ด์คํ๊ฒ ์๊ณ ์๋ ์ง์๋ค๊ณผ ์ค์๋ค์ด ๋ฌธ์ ์๋๋ฐ์, ๋ค์๋ ์ด๋ฐ ์ผ์ด ์ผ์ด๋์ง ์๋๋ก ๋ฉ๋ชจํด๋๋ ค๊ณ ํฉ๋๋ค.
Container
let container = try decoder.singleValueContainer()
let coordinates = try container.decode([Double].self)
์ธ์ฝ๋ฉ๊ณผ ๋์ฝ๋ฉ์ ํ ๋ ์ฌ์ฉํ๋ Container.. ์ ํํ ์ด๋ป๊ฒ ์ฌ์ฉํ๋์ง ์๊ณ ๊ณ์ ๊ฐ์?
์ ๋ ์ ๋ชฐ๋ผ์ ใ .. ์ด๋ฒ์ ํ ๋ฒ ์์๋ดค์ต๋๋ค.
// Data: [23.538399, -138.438982]
public init(from decoder: Decoder) throws {
let container = try decoder.unkeyedContainer()
let coordinates = try container.decode([Double].self)
guard coordinates.count == 2 else {
throw DecodingError.dataCorruptedError(in: container,
debugDescription: "Coordinate ๊ฐ์ 2๊ฐ ๊ฐ์ผ๋ก ์ด๋ฃจ์ด์ง ๋ฐฐ์ด์ด์ด์ผ ํฉ๋๋ค.")
}
self.latitude = coordinates[0]
self.longitude = coordinates[1]
}
์ฐธ๊ณ ๋ก ๋ฌธ์ ๊ฐ ๋๋ ์ฝ๋๋ ์ ์ฝ๋์ ๋๋ค.
์ด๋ค ๋ถ๋ถ์ด ๋ฌธ์ ์ธ์ง ๋ชจ๋ฅด์๊ฒ ๋ค๋ฉด.. ๋ฐ๋ผ์ค์์ฃ .
KeyedDecodingContainer
CodingKey
๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ์์
๋๋ค.
// Data:
// {
// "name": "S045 ์ด์ฐฝ์ค"
// "id": "1D723110-BD79-4839-9A30-1629BF49CFE8"
// }
struct SomeData: Decodable {
var name: String?
let id: UUID
enum CodingKeys: String, CodingKey {
case name = "title"
case id = "_id"
}
}
CodingKey ํ๋กํ ์ฝ์ ์ฑํํ๋ ์ด๊ฑฐํ์ ๋ง๋ค์ด ๋งค์นญ์์ผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.name = try container.decodeIfPresent(String.self, forKey: .name) ?? ""
self.id = try container.decode(UUID.self, forKey: .id)
}
์ผ๋ฐ์ ์ผ๋ก ๋ง์ด ์ฌ์ฉ๋๋ ๋ฐฉ์์ด๊ณ , ์ ๋ํ ์ต์ํ๊ธฐ ๋๋ฌธ์ ๋์ด๊ฐ๊ฒ ์ต๋๋ค.
SingleValueContainer
๋ฌธ์ ๊ฐ ๋์๋ SingleValueContainer์ ๋๋ค.
๊ทธ๋ฐ๋ฐ ์ฌ์ค, ์ ์๊ณ ์์ผ๋ฉด ์ด๊ฑฐ๋งํผ ๊ฐ๋จํ ๊ฒ๋ ์์ต๋๋ค.
๋ง ๊ทธ๋๋ก ๋จ์ํ ํ๋์ ๊ฐ๋ง ๋ก ๋ค์ด์์ ๋ ์ฌ์ฉ๋๊ธฐ ๋๋ฌธ์ ๋๋ค.
// Data: "S045 ์ด์ฐฝ์ค"
struct OneData: Decodable {
let name: String
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
self.name = try container.decode(String.self)
}
}
๋ค.. ์๊ณ ๋ณด๋๊น ์ฐธ ์ฝ์ฃ ..
UnkeyedContainer
UnkeyedContainer ๊ฐ์ ๊ฒฝ์ฐ๊ฐ ์กฐ๊ธ ํท๊ฐ๋ฆฌ๋ฉด์๋ ํน์ดํฉ๋๋ค.
๋ฐฐ์ด๋ก ๊ฐ์ด ๋ค์ด์ค๋๋ฐ, ๊ทธ ํ์ ๋ค์ด ์ ๊ฐ๊ฐ์ผ ๋ ์ฌ์ฉ๋ฉ๋๋ค.
// Data: ["S045 ์ด์ฐฝ์ค", 0.45, true, 28]
struct UnkeyedData: Decodable {
var name: String?
var id: Double?
var isCheckedIn: Bool?
var age: Int?
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
self.name = try container.decode(String?.self)
self.id = try container.decode(Double?.self)
self.isCheckedIn = try container.decode(Bool?.self)
self.age = try container.decode(Int?.self)
}
}
๋ฐฐ์ด ์์ ์ฌ๋ฌ ํ์ ๋ค์ด ์์ง๋ง, ํ๋กํผํฐ ์์๋๋ก ๋งค์นญํด ๋์ฝ๋ฉํด์ค๋๋ค.
์๋ฌ ํด๊ฒฐ
// Data: [23.538399, -138.438982]
public init(from decoder: Decoder) throws {
let container = try decoder.unkeyedContainer()
let coordinates = try container.decode([Double].self)
guard coordinates.count == 2 else {
throw DecodingError.dataCorruptedError(in: container,
debugDescription: "Coordinate ๊ฐ์ 2๊ฐ ๊ฐ์ผ๋ก ์ด๋ฃจ์ด์ง ๋ฐฐ์ด์ด์ด์ผ ํฉ๋๋ค.")
}
self.latitude = coordinates[0]
self.longitude = coordinates[1]
}
๊ทธ๋ผ ๋์๊ฐ์ ์ด ์ฝ๋๋ ๋ญ๊ฐ ๋ฌธ์ ์์๊น์?
๋ฐฉ์์ singleValueContainer
๋ฐฉ์์ ์ฐ๊ณ ์์ง๋ง, unkeyedContainer
๋ฅผ ์ฐ๊ณ ์๊ธฐ ๋๋ฌธ์
๋๋ค.
UnkeyedContainer๋ฅผ ์ฌ์ฉํ ์๋ ์๊ฒ ์ฃ .
// Data: [23.538399, -138.438982]
public init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
self.latitude = try container.decode(Double.self)
self.longitude = try contianer.decode(Double.self)
}
์ด๋ ๊ฒ ์ฌ์ฉํ ์๋ ์์์ ๊ฒ๋๋ค.
๊ฒฐ๊ณผ
์ ์ฌ์ฉํ์ง ์๋ decode ๋ฐฉ์์ ๋ํด ์ด๋ฒ ๊ธฐํ์ ๋ค์ ์์๋ดค์ต๋๋ค.
๊ทธ๋ฅ ๋๋๋๋ก ์ฐ๋ ๋๋์ด ์์๋๋ฐ ์ง๊ธ์ด๋ผ๋ ์์๋ณด๊ฒ ๋์ด์ ๋คํ์ด๋ค์.
ํ์ ์ ๊ฐ๋ฉด ์ด ๋ฌธ์ ๊ฐ ์๋นํ ํด ๊ฒ ๊ฐ์๋ฐ ์ด๋ป๊ฒ ํด๊ฒฐํ ์ง๋ ๊ถ๊ธํฉ๋๋ค.