관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 데이터 변환 개념 Data, Encodable, Decodable, Codable, JSONSerialization, [String: Any] (struct, json, data) 본문

iOS 응용 (swift)

[iOS - swift] 데이터 변환 개념 Data, Encodable, Decodable, Codable, JSONSerialization, [String: Any] (struct, json, data)

jake-kim 2021. 10. 5. 23:20

필수 개념, Data 형

  • 메모리 안의 바이트가 저장될 수 있는 `바이트 버퍼`
  • `바이트 버퍼`: 운영체제의 커널이 관리하는 시스템 메모리를 직접 사용할 수 있기 때문에 데이터의 저장, 로드가 가능
  • swift는 URLSession으로 dataTask를 만들어, 네트워크 호출을 하면 응답으로 Data형을 받는데, 이는 저장, 로드, 변환이 쉽기 때문에 Data로 받는 것

  • 자주 사용되는 것은 json데이터를 struct형으로 변경하거나, 반대로 struct형에서 json으로 변경할 때 먼저 `Data`형으로 변경한 다음 원하는 데이터형으로 변경하여 사용

ex) UserDefaults에 struct 자료형을 Encoder, Decoder를 이용하여 저장하는 방법: https://ios-development.tistory.com/702

Encodable

  • Encodable: `Data`형으로 변형할 수 있는 타입 (JSON형)
    • Sample타입은 Encodable을 준수하고 있으므로, Sample객체는 Data형의 객체로 변형 가능
// Encodable 준수: Data형으로 변형 가능한 자료형
struct Sample: Encodable {
    let a: Int
    let b: Int
}
  • JSONEncoder: JSON 데이터 타입으로 인코딩할 수 있는 객체

  • json 데이터 타입으로 변환
struct Sample: Encodable {
    let a: Int
    let b: Int
}

let sample = Sample(a: 0, b: 0)
let jsonEncoder = JSONEncoder()
jsonEncoder.outputFormatting = .prettyPrinted
let data = try jsonEncoder.encode(sample)

print(data) // 13 bytes
print(String(data: data, encoding: .utf8)) // "{\n  \"a\" : 0,\n  \"b\" : 0\n}"

Decodable

  • `Data`형을 struct와 같은 것으로 변환할 수 있는 타입
    • Sample2는 Decodable을 준수하고 있기 때문에, Data형을 Sample2에서 정의한 프로퍼티에 매핑이 가능
struct Sample2: Decodable {
    let aVal: Int
    let bVal: Int

    enum CodingKeys: String, CodingKey {
        case aVal = "a"
        case bVal = "b"
    }
}
  • JSONDecoder(): data타입인 json 객체를 모델로 변형할 수 있는 타입

  • 위에서 sample으로 만든 json 데이터 타입을 struct형으로 변형
...
let data = try jsonEncoder.encode(sample)

struct Sample2: Decodable {
    let aVal: Int
    let bVal: Int

    enum CodingKeys: String, CodingKey {
        case aVal = "a"
        case bVal = "b"
    }
}
let jsonDecoder = JSONDecoder()
let sample2 = try jsonDecoder.decode(Sample2.self, from: data)
print(sample2) // Sample2(aVal: 0, bVal: 0)

Codable

  • Decodable과 Encodable을 동시에 가지고 있는 타입

struct to [String: Any]

  • json데이터는 타입 캐스팅으로 쉽게 [String: Any]형으로 변형 가능하므로 Data형을 먼저 json형식의 Data형으로 변형
    • json데이터를 [String: Any]로 변경: jsonData as? [String: Any]

  • extension Encodable로 추가
extension Encodable {
    func toDictionary() throws -> [String: Any]? {
        let data = try JSONEncoder().encode(self)
        let jsonData = try JSONSerialization.jsonObject(with: data)
        return jsonData as? [String: Any]
    }
}
  • 위에서 사용된 JSONSerialization 이란?

  • Foundation 객체로 변환하는 객체이고, JSONSerilization.jsonObject(with data: Data)을 통해 Data형을 Any형으로 변환할 수 있는 역할

* 참고

- Data: https://developer.apple.com/documentation/foundation/data

- Encodable: https://developer.apple.com/documentation/swift/encodable

- JSONEncoder: https://developer.apple.com/documentation/foundation/jsonencoder

- Decodable: https://developer.apple.com/documentation/swift/decodable

- JSONDecoder: https://developer.apple.com/documentation/foundation/jsondecoder

- Codable: https://developer.apple.com/documentation/swift/codable

- JSONSerialization: https://developer.apple.com/documentation/foundation/jsonserialization

- jsonObject(with:options:): https://developer.apple.com/documentation/foundation/jsonserialization/1415493-jsonobject

 

Comments