μΈλΆ νν νμ(JSON, λ±)μ νΈνλλλ‘ λ°μ΄ν° μ νμ μΈμ½λ© λ° λμ½λ©ν μ μλλ‘ λ§λ€κΈ°
Encodable
λ° Decodable
νλ‘ν μ½μ ꡬνν¨μΌλ‘μ¨ μ΄ μ κ·Ό λ°©μμ μ±νν μ μμEncoder
μ Decoder
ꡬν체λ€μ΄ λ°μ΄ν°λ₯Ό κ°μ Έμμ JSON λλ νλ‘νΌν° 리μ€νΈμ κ°μ μΈλΆ νν νμμΌλ‘ μΈμ½λ©νκ±°λ λμ½λ©ν μ μμνλ‘νΌν° 리μ€νΈ
- λ€μν λ°μ΄ν° μ νμ μ§μνλ κ³μΈ΅μ μΈ κ΅¬μ‘°
- λ€μμ μ±μ κ΅¬μ± μ€μ μ μ μ₯νκΈ° μν νλ‘νΌν° 리μ€νΈ
<dict> <key>Theme</key> <string>Dark</string> <key>Language</key> <string>English</string> <key>Notifications</key> <true/> </dict>
Encodable
κ³Ό Decodable
νλ‘ν μ½μ κ²°ν©ν Codable
μ μ±ννλλ‘ μ μΈCodable
νκ² λ§λ¬Codable
λ‘ λ§λλ κ°μ₯ κ°λ¨ν λ°©λ²μ ν΄λΉ νμ
μ μμ±λ€μ μ΄λ―Έ Codable
μΈ νμ
μΌλ‘ μ μΈνλ κ²String
, Int
, Double
κ³Ό κ°μ νμ€ λΌμ΄λΈλ¬λ¦¬ νμ
, κ·Έλ¦¬κ³ Date
, Data
, URL
κ³Ό κ°μ Foundation
νμ
μ ν¬ν¨Codable
μΈ μ΄λ€ νμ
μ΄λ κ°μ, ν΄λΉ νμ
μ΄ Codable
μ μ€μνλ€λ μ μΈλ§ νλ©΄ μλμΌλ‘ Codable
μ μ€μνκ² λ¨struct Landmark {
var name: String
var foundingYear: Int
}
Landmark
ꡬ쑰체μ Codable
μ μμ λͺ©λ‘μ μΆκ°νλ©΄, Encodable
κ³Ό Decodable
μ λͺ¨λ νλ‘ν μ½ μꡬμ¬νμ μΆ©μ‘±νκ² λ¨struct Landmark: Codable {
var name: String
var foundingYear: Int
// Landmark now supports the Codable methods init(from:) and encode(to:),
// even though they aren't written as part of its declaration.
}
Codable
μ μ±ννλ©΄ λ΄μ₯λ λ°μ΄ν° νμ λ° μ¬μ©μ μ μ μΈμ½λ λ° λμ½λκ° μ 곡νλ νμκ³Όμ μ§λ ¬ν λ° μμ§λ ¬νκ° κ°λ₯ν΄μ§Landmark
ꡬ쑰체λ PropertyListEncoder
λ° JSONEncoder
ν΄λμ€λ₯Ό μ¬μ©νμ¬ μΈμ½λ©μ΄ κ°λ₯ν΄μ§Landmark
μ체μλ λͺ
μμ μΌλ‘ νλ‘νΌν° 리μ€νΈλ JSONμ μ²λ¦¬νλ μ½λκ° μλλΌλ κ°λ₯Codable
λ‘ κ΅¬μ±λ λ€λ₯Έ μ¬μ©μ μ μ νμ
μλ μ μ©λ¨Codable
μ μ€μνλ€λ©΄, μ¬μ©μ μ μ νμ
λ Codable
μ΄ λ μ μμLandmark
ꡬ쑰체μ location
νλ‘νΌν°λ₯Ό μΆκ°νμ λ μλ Codable
μ€μκ° μ μ©λ κ²μ 보μ¬μ€struct Coordinate: Codable {
var latitude: Double
var longitude: Double
}
struct Landmark: Codable {
// Double, String, and Int all conform to Codable.
var name: String
var foundingYear: Int
// Adding a property of a custom Codable type maintains overall Codable conformance.
var location: Coordinate
}
Array
, Dictionary
, Optional
κ³Ό κ°μ Built-in types
μ Codable
μ μ€μν¨Built-in types
μ΄ Codable
νμ
μ ν¬ν¨νκ³ μμ λ μλμΌλ‘ Codable
μ μ€μνκ² λ¨Landmark
μ Coordinate
μΈμ€ν΄μ€μ λ°°μ΄μ μΆκ°ν΄λ μ 체 ꡬ쑰체λ μ¬μ ν Codable
μ μ€μν¨Landmark
λ΄μ λ΄μ₯λ Codable
νμ
μ μ¬μ©νμ¬ μ¬λ¬ νλ‘νΌν°λ₯Ό μΆκ°νμ λ μλ Codable
μ€μκ° μ μ©λλ μμstruct Landmark: Codable {
var name: String
var foundingYear: Int
var location: Coordinate
// Landmark is still codable after adding these properties.
var vantagePoints: [Coordinate]
var metadata: [String: String]
var website: URL?
}
Codable
μ μλ°©ν₯ μΈμ½λ© λ° λμ½λ© μ§μμ΄ νμνμ§ μμ μ μμEncodable
μ μ€μλ‘ μ μΈνλ©΄ λ¨Decodable
μ μ€μλ‘ μ μΈνλ©΄ λ¨Landmark
ꡬ쑰체μ λ체 μ μΈμ 보μ¬μ€struct Landmark: Encodable {
var name: String
var foundingYear: Int
}
struct Landmark: Decodable {
var name: String
var foundingYear: Int
}
Codable
μ νμ CodingKey
νλ‘ν μ½μ μ€μνλ νΉμν μ€μ²© μ΄κ±°νμΈ CodingKeys
λ₯Ό μ μΈν μ μμcase
μ μ΄λ¦μ μ νμ ν΄λΉ property
μ μ§μ ν μ΄λ¦κ³Ό μΌμΉν΄μΌ ν¨Decoding
μΈμ€ν΄μ€μ μμ κ²½μ° λλ μΈμ½λ©λ ννμ νΉμ μμ±μ ν¬ν¨μν€μ§ μμμΌνλ κ²½μ° CodingKeys
μ΄κ±°νμμ μμ±μ μ μΈμμΌμΌ ν¨CodingKeys
μμ μ μΈλ μμ±μ Decodable
λλ Codable
μ λν μλ μ€μλ₯Ό λ°κΈ° μν΄ κΈ°λ³Έκ°μ΄ νμν¨CodingKeys
μ΄κ±°νμ rawValue
λ‘ String
μ μ§μ νμ¬ λ체 ν€λ₯Ό μ 곡ν μ μμcase
μ rawValue
λ‘ μ¬μ©νλ λ¬Έμμ΄μ μΈμ½λ© λ° λμ½λ© μ€μ μ¬μ©λλ ν€ μ΄λ¦case
μ΄λ¦κ³Ό rawValue
κ°μ μ°κ΄ κ΄κ³λ₯Ό ν΅ν΄ λ°μ΄ν° ꡬ쑰λ₯Ό Swift API Design Guidelines
μ λ°λΌ λͺ
λͺ
ν μ μμΌλ©° μ§λ ¬νλ λ°μ΄ν°(JSON, λ±)μ μ΄λ¦, ꡬλμ λ° λλ¬Έμμ μΌμΉμν¬ νμκ° μμ΄μ§Landmark
ꡬ쑰체μ name
λ° foundingYear
μμ±μ λν΄ μΈμ½λ© λ° λμ½λ©ν λ λ체 ν€λ₯Ό μ¬μ©νλ λ°©λ²μ 보μ¬μ€struct Landmark: Codable {
var name: String
var foundingYear: Int
var location: Coordinate
var vantagePoints: [Coordinate]
enum CodingKeys: String, CodingKey {
case name = "title"
case foundingYear = "founding_date"
case location
case vantagePoints
}
}
Encodable
κ³Ό Decodable
μ ꡬννμ¬ μ¬μ©μ μ μ μΈμ½λ© λ° λμ½λ© λ‘μ§μ μ μν μ μμCoordinate
κ΅¬μ‘°μ²΄κ° μΆκ° μ λ³΄μΈ additionalInfo
컨ν
μ΄λ λ΄μ ν¬ν¨λ elevation
μμ±μ μ§μνλλ‘ νμ₯λ¨struct Coordinate {
var latitude: Double
var longitude: Double
var elevation: Double
enum CodingKeys: String, CodingKey {
case latitude
case longitude
case additionalInfo
}
enum AdditionalInfoKeys: String, CodingKey {
case elevation
}
}
Coordinate
νμ
μ μΈμ½λ©λ νμμ λ λ²μ§Έ μμ€μ μ€μ²© μ 보λ₯Ό ν¬ν¨νκ³ μκΈ° λλ¬Έμ ν΄λΉ νμ
μ Encodable
λ° Decodable
νλ‘ν μ½μ μ±ννλ λ° λ κ°μ μ΄κ±°νμ μ¬μ©λ λ²μ§Έ μμ€μ μ€μ²© μ 보(second level of nested information)
Coordinate
νμ μ μΈμ½λ©λ νμμμ μΆκ°λ‘ ν¬ν¨λλ λ°μ΄ν°μ ꡬ쑰λ₯Ό μλ―Έ- μλ₯Ό λ€μ΄ JSONμμ
additionalInfo
κ°μ²΄ μμelevation
μ΄ ν¬ν¨ λ ꡬ쑰
Coordinate
ꡬ쑰체λ₯Ό νμ₯νμ¬ Decodable
νλ‘ν μ½μ μ€μνκΈ° μν΄ νμν μ΄λμ
λΌμ΄μ μΈ init(from:)
μ ꡬνν©λλ€.extension Coordinate: Decodable {
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
latitude = try values.decode(Double.self, forKey: .latitude)
longitude = try values.decode(Double.self, forKey: .longitude)
let additionalInfo = try values.nestedContainer(keyedBy: AdditionalInfoKeys.self, forKey: .additionalInfo)
elevation = try additionalInfo.decode(Double.self, forKey: .elevation)
}
}
init(from:)
λ©μλλ Decoder
λ₯Ό 맀κ°λ³μλ‘ λ°κ³ , λμ½λ© μμ
μ μνdecoder.container(keyedBy:)
λ©μλλ₯Ό μ¬μ©νμ¬ λμ½λμ 컨ν
μ΄λλ₯Ό μ»μcontainer(keyedBy:)
λ©μλλ₯Ό μ¬μ©νμ¬ values
λ³μμ λν 컨ν
μ΄λλ₯Ό μμ± values
컨ν
μ΄λλ CodingKeys
μ΄κ±°νμ ν€ νμ
μΌλ‘ μ¬μ©νλ©°, ν΄λΉ μ΄κ±°νμ latitude
μ longitude
μμ±μ λμνλ μ½λ© ν€λ₯Ό λνλdecode(_:forKey:)
λ©μλλ₯Ό μ¬μ©νμ¬ μ»¨ν
μ΄λμμ κ° μμ±μ κ°μ λμ½λ©νκ³ , μ΄λ₯Ό latitude
μ longitude
μμ±μ ν λΉnestedContainer(keyedBy:forKey:)
λ©μλλ₯Ό μ¬μ©νμ¬ additionalInfo
λ³μμ λν μ€μ²©λ 컨ν
μ΄λλ₯Ό μμ±AdditionalInfoKeys
μ΄κ±°νμ ν€ νμ
μΌλ‘ μ¬μ©νλ©°, ν΄λΉ μ΄κ±°νμ elevation
μμ±μ λμνλ μ½λ© ν€λ₯Ό λνλdecode(_:forKey:)
λ©μλλ₯Ό μ¬μ©νμ¬ μ€μ²©λ 컨ν
μ΄λμμ elevation
μμ±μ κ°μ λμ½λ©νκ³ , μ΄λ₯Ό elevation
μμ±μ ν λΉinit(from:)
λ©μλλ λμ½λ© μμ
μ μλ£νκ³ , Coordinate
ꡬ쑰체μ λͺ¨λ μμ±μ΄ μ¬λ°λ₯΄κ² μ΄κΈ°νλ μνλ‘ μΈμ€ν΄μ€λ₯Ό μμ±ν¨μ»¨ν μ΄λ
- 컨ν μ΄λλ λμ½λ© μμ μμ μ¬μ©λλ ꡬ쑰체λ‘, λμ½λ©ν λ°μ΄ν°μ λν ν€-κ° μμ΄λ μμ°¨μ μΈ κ°λ€μ λ΄κ³ μμ
KeyedDecodingContainer
λλUnkeyedDecodingContainer
νλ‘ν μ½μ μ€μνλ μΈμ€ν΄μ€
Coordinate
μΈμ€ν΄μ€μ λ μμ±μΈ latitude
μ longitude
μ Swift νμ€ λΌμ΄λΈλ¬λ¦¬μμ μ 곡νλ KeyedContainer
APIλ₯Ό μ¬μ©νμ¬ μ΄κΈ°νλ¨Decoder
μΈμ€ν΄μ€λ₯Ό ν΅ν΄ μ κ·Όν μ μμCoordinate
κ΅¬μ‘°μ²΄κ° Encodable
νλ‘ν μ½μ μ€μνκΈ° μν΄ νμν λ©μλμΈ encode(to:)
λ₯Ό ꡬννλ λ°©λ²extension Coordinate: Encodable {
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(latitude, forKey: .latitude)
try container.encode(longitude, forKey: .longitude)
var additionalInfo = container.nestedContainer(keyedBy: AdditionalInfoKeys.self, forKey: .additionalInfo)
try additionalInfo.encode(elevation, forKey: .elevation)
}
}
encode(to:)
λ©μλμ ꡬνμ μ΄μ μμ μ λμ½λ© μμ
μ μμΌλ‘ μν