๐Ÿš€ iOS ๋„คํŠธ์›Œํ‚น ์ •๋ณตํ•˜๊ธฐ : Codable Protocol ( JSON Encoding / Decoding)

a.veryยท2022๋…„ 9์›” 25์ผ
0

Codable

typealias Codable = Decodable & Encodable
  • ์ž์‹ ์„ "์™ธ๋ถ€ํ‘œํ˜„"์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ฑฐ๋‚˜ ๋ณ€ํ™œํ•  ์ˆ˜ ์žˆ๋Š” ํƒ€์ž…
  • Codable ์€ Encodable ๊ณผ Decodable protocol๋กœ ๊ตฌ์„ฑ๋œ ์œ ๋‹ˆ์˜จ ํƒ€์ž…(union type)์œผ๋กœ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • "์™ธ๋ถ€ํ‘œํ˜„" : ๋ณดํ†ต JSON์ด๋‚˜, property-list...
  • ํ”„๋กœํ† ์ฝœ๋กœ Class, Enum, Struct ๋ชจ๋‘์—์„œ ์ฑ„ํƒ๊ฐ€๋Šฅ

Codable ์„ ์ฑ„ํƒํ–ˆ๋‹ค = Class, Struct, Enum์„ย serialize /ย deserializeํ•  ์ˆ˜ ์žˆ๋‹ค

Decodable, Encodable

Codable : Decodable ๊ณผ Encodable ์„ ๋ชจ๋‘ ์ฑ„ํƒ

Decodable : ์ž์‹ ์„ ์™ธ๋ถ€ํ‘œํ˜„์œผ๋กœ ๋””์ฝ”๋”ฉ ํ•  ์ˆ˜ ์žˆ๋Š” ํƒ€์ž… (ex - JSON -> ์ž์‹ )

Encodable : ์ž์‹ ์„ ์™ธ๋ถ€ํ‘œํ˜„์œผ๋กœ ์ธ์ฝ”๋”ฉ ํ•  ์ˆ˜ ์žˆ๋Š” ํƒ€์ž… (ex - ์ž์‹  -> JSON)

Encoding

PropertyListEncoder ๋‚˜ JSONEncoder ํด๋ž˜์Šค๋กœ ์ธ์ฝ”๋”ฉ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • .encode ๋ฉ”์†Œ๋“œ๋Š” Encodable ํƒ€์ž…์„ ์ค€์ˆ˜ํ•˜๋Š” T ๋ฅผ JSON Data ๋กœ ๋ฆฌํ„ดํ•ด์ค€๋‹ค

๐Ÿš— ์˜ˆ์‹œ๋ฅผ ๋ณด์ž!

1. Codable ํ”„๋กœํ† ์ฝœ์„ ์ฑ„ํƒํ•œ Car ๊ตฌ์กฐ์ฒด๊ฐ€ ์žˆ๋‹ค

struct Car: Codable {
    let name: String
    let brand: String
    let age: Int
}

2. Car ๊ตฌ์กฐ์ฒด๋ฅผ JSON ์œผ๋กœ ์ธ์ฝ”๋”ฉํ•ด๋ณด์ž

let data = Car(name: "taycan", brand: "porsche", age: 2)
let encoder = JSONEncoder() // 1๏ธโƒฃ JSON Encoder ์„ ์–ธ 
let jsonData = try? encoder.encode(data) // 2๏ธโƒฃ Data ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ 
if let jsonData = jsonData, let jsonString = String(data: jsonData, encoding: .utf8) {
    print("๐Ÿš—")
    print(jsonString)
    print("๐Ÿš—")
}  // 3๏ธโƒฃ Data ํƒ€์ž…์„ String ์œผ๋กœ ๋งŒ๋“ฌ 

// โœ… if let ์ธ ์ด์œ  
// 1. try? -> jsonData ๊ฐ€ optional ์ด๋‹ค.
// 2. 2. String(data: , encoding: )์˜ ๋ฆฌํ„ดํƒ€์ž… ->  String? => optional

์ถœ๋ ฅ๊ฒฐ๊ณผ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค

๐Ÿš—
{"name":"taycan","brand":"porsche","age":2}
๐Ÿš—

๊ทผ๋ฐ json ์€ ์•ฝ๊ฐ„ ๊ทธ ๋ชจ์–‘์ด ๊ตญ๋ฃฐ์ธ๋ฐ....?
๊ทธ ๋ชจ์–‘ ์„ ์•„๋ž˜์—์„œ ๋งŒ๋“ค์–ด๋ณด์ž


3. encoder์˜ ์ถœ๋ ฅ๊ฒฐ๊ณผ๋ฅผ ์ด์˜๊ฒŒ ๋งŒ๋“ค์–ด๋ณด์ž ๐ŸŒˆ (JSONEncoder.OutputFormatting)

JSONEncoder.OutputFormatting ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค!

encoder.outputFormatting = .prettyPrinted // json ๋ชจ์–‘์œผ๋กœ ์ด์˜๊ฒŒ ์ถœ๋ ฅ 
encoder.outputFormatting = .sortedKeys  // key ๋ฅผ abcd ์ˆœ์œผ๋กœ ์ถœ๋ ฅ 
encoder.outputFormatting = .withoutEscapingSlashes // *escaping slash๋ฅผ ์ œ๊ฑฐ
  • escaping slash๋ฅผ ์ œ๊ฑฐ
    url๊ฐ’์„ "https://google.com" ์œผ๋กœ ๋ณด๋ƒˆ๋Š”๋ฐ, ์‹ค์ œ json ํŒŒ์ผ์—์„œ "https:\/\/google.com"๋กœ ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Œ

์—ฌ๋Ÿฌ๊ฐœ๋ฅผ ํ•œ๋ฒˆ์— ์ ์šฉ

encoder.outputFormatting = [.prettyPrinted, .sortedKeys]

์ง !

Decoding

์ด๋ฒˆ์—” ๋ฐ˜๋Œ€๋กœ Decoding ์„ ํ•ด๋ด…์‹œ๋‹ค~!~~

1. Codable ํ”„๋กœํ† ์ฝœ์„ ์ฑ„ํƒํ•œ Car ๊ตฌ์กฐ์ฒด๊ฐ€ ์žˆ๋‹ค

struct Car: Codable {
    let name: String
    let brand: String
    let age: Int
}

2. Car ๊ตฌ์กฐ์ฒด๋ฅผ JSON ์œผ๋กœ ๋””์ฝ”๋”ฉํ•ด๋ณด์ž

// 1๏ธโƒฃ JSONDecoder ์„ ์–ธ
let decoder = JSONDecoder()

// 2๏ธโƒฃ ์ž„์‹œ๋กœ JSON Data๋ฅผ ๋งŒ๋“ค์–ด๋ด…์‹œ๋‹ค (์œ„์—์„œ ๋‚ด์šฉ ์‚ฌ์šฉ)
let data = jsonString.data(using: .utf8)

// 3๏ธโƒฃ .decode ๋ฉ”์†Œ๋“œ๋กœ data -> ์ธ์Šคํ„ด์Šค
if let data = data, let myCar = try? decoder.decode(Car.self, from: data) {
    print("๐Ÿš€๐Ÿš€๐Ÿš€๐Ÿš€")
    print(myCar.name)
    print(myCar.brand)
    print(myCar.age)
    print("๐Ÿš€๐Ÿš€๐Ÿš€๐Ÿš€")
}	

์ถœ๋ ฅ๊ฒฐ๊ณผ

๐Ÿš€๐Ÿš€๐Ÿš€๐Ÿš€
taycan
porsche
2
๐Ÿš€๐Ÿš€๐Ÿš€๐Ÿš€


JSONDecoder ์˜ .decode ๋ฉ”์†Œ๋“œ๋ฅผ ๋ด…์‹œ๋‹ค

  • type : Decodable ์„ ์ค€์ˆ˜ํ•ด์•ผํ•จ / JSON์œผ๋กœ ๋งŒ๋“ค๊ณ  ์‹ถ์€ ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ์ •์˜ (ํƒ€์ž….self)
  • data : Decoding ํ•˜๋ ค๋Š” ๋ฐ์ดํ„ฐ

Nullable & Optional Key

ํŠน์ •ํ•„๋“œ์˜ ๊ฐ’์ด nullable ํ•˜๊ฑฐ๋‚˜ optional ํ•œ key์˜ ๊ฒฝ์šฐ struct์„ ์•„๋ž˜์™€ ๊ฐ™์ด ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค!

struct Car: Codable {
    let name: String
    let brand: String
    let age: Int?
}

๊ธฐ๋ณธ๊ฐ’ ํ• ๋‹น์€ ์•„๋ž˜์ฒ˜๋Ÿผ

struct Car: Codable {
    let name: String
    let brand: String
    let age: Int = 0
}

References

https://zeddios.tistory.com/373
https://inuplace.tistory.com/895?category=1034357
https://medium.com/humanscape-tech/swift%EC%97%90%EC%84%9C-codable-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0-367587c5a591
https://medium.com/doyeona/codable-decodable-encodable-feat-json-5643dc3d7766
http://minsone.github.io/programming/swift-codable-and-exceptions-extension
https://kyungmosung.github.io/2020/08/17/swift-codable-enum/

https://developer.apple.com/documentation/swift/codable
https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types

profile
๐Ÿššchanhee-jeong.tistory.com ๐Ÿš€ github.com/chaneeii/iOS-Study-Log

0๊ฐœ์˜ ๋Œ“๊ธ€