
μΈλΆ νν νμ(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:)λ©μλμ ꡬνμ μ΄μ μμ μ λμ½λ© μμ
μ μμΌλ‘ μν