Swift

[Swift] JSON 객체를 구조체로 변환하기

일반적으로 Swift에서 API를 통한 HTTP통신으로 데이터를 주고받을때 Data 타입의 객체를 사용했는데, 소켓 통신을 하면서 JSON 형식의 객체(JSON Object)를 사용했다. JSON 객체를 바로 사용하기엔 불편함이 많아서 구조체로 바꾸기 위해 사용했던 방법을 기록한다.


이전까지 뜻을 정확히 모른 상태에서 사용하다가 이번 기회에 JSON에 대해 알아봤다.

JSON이란?
JavaScript Object Notation의 약자로 자바스크립트 언어에서 배열 또는 키-값 쌍으로 이루어진 데이터 객체를 전달하기 위해 사람이 읽을 수 있는 텍스트 형식을 사용하는 포맷이다.

프로그래밍 언어와 플랫폼에 독립적이라는 특징이 있어서 다양한 환경에서 사용되며 Swift에서도 객체를 JSON 형식으로 변환하거나 반대로 JSON 형식의 데이터를 객체로 변환하는게 가능하다.

 

JSON 형식에 사용되는 기본 자료형과 그에 대응되는 Swift의 자료형은 다음과 같다.

  1. 수 (Number) → Int, Double
  2. 문자열(String) → String
  3. 참, 거짓 (Boolean) → Bool
  4. 배열 (Array) → Array
  5. 객체 (Object) → Dictionary
  6. null → nil

다르게 말하면, JSON 형식으로 주고 받는 데이터의 타입은 위에서 명시된 것만 가능하다. 또한 JSON 형식으로 보내는 메시지 단위는 객체 또는 배열만 가능하므로 (socket.io 기준) 소켓을 통해 데이터를 전달하기 위해 Swift의 Data 객체를 사용할 수 없다는 것에 유의하자.


 {
    "name": "Jonson",
    "age": 24,
    "sex": "MALE",
    "hobby": "soccer"
 }

예를 들어 Swift에서 위처럼 키-값 쌍으로 이루어진 데이터 객체를 전달하려고 한다면 아래와 같은 사전을 만들어 전달하면 된다.

 let jsonObject: [String: Any] = { "name": "Jonson", "age": 24, "sex": "MALE", "hobby": "soccer" }

 

만약 jsonObject를 구조체로 변환하고 싶다면 먼저 JSONSerialization 객체를 사용해야한다. 

JSONSerialization
An object that converts between JSON and the equivalent Foundation objects.

※ Serialize (직렬화)
네트워크를 통해 객체를 주고 받기 위해서 객체를 특수한 형식으로 가공하는 것.
Swift에서는 Encode와 Decode 라는 용어를 사용한다. 즉, Serialize = Encode 이고 Deserialize = Decode

JSONSerialization은 jsonObject라는 Dictionary(Foundation object)를 JSON 형식의 Data 객체로 변환해주는 기능을 하는데, 변환된 Data 객체를 Codable 프로토콜을 사용해 다시 구조체로 Decoding 해줄 것이다.

enum Sex: String, Codable {
    
    case male = "MALE"
    case female = "FEMALE"
    
}

struct Human: Codable {
    
    var name: String
    var age: Int
    var sex: Sex
    var hobby: String?
    
}

Codable 프로토콜을 따르는 구조체를 선언해주고 각 프로퍼티 이름을 JSON 형식의 키와 일치시켜준다. 이때 "sex"키에 해당하는 값은 "MALE" 또는 "FEMALE" 이므로 "sex" 키의 값과 타입이 일치하는 기본값을 가진 열거형으로 변환이 가능하다. "hobby" 키의 값이 null일 수 있다면 옵셔널 타입으로 대응할 수 있다.

guard let jsonData = try? JSONSerialization.data(withJSONObject: jsonObject) else { return }
            
guard let human = try? JSONDecoder().decode(Human.self, from: jsonData) else { return }

이런 방식으로 생성된 Human 타입의 구조체를 사용해서 JSON 형식으로 전달받은 객체의 데이터를 쉽게 사용할 수 있다.


참고 링크

https://ko.wikipedia.org/wiki/JSON

 

JSON - 위키백과, 우리 모두의 백과사전

JSON(제이슨[1], JavaScript Object Notation)은 속성-값 쌍(attribute–value pairs), 배열 자료형(array data types) 또는 기타 모든 시리얼화 가능한 값(serializable value) 또는 "키-값 쌍"으로 이루어진 데이터 오브젝트

ko.wikipedia.org

'Swift' 카테고리의 다른 글

[Swift] COW(Copy-on-Write)에 대하여  (0) 2022.07.28
[Swift] Singleton과 Thread-Safe  (0) 2022.05.12
[Swift] 초기화(Initialization)란?  (0) 2022.05.12