스위프트

Codable 이해

강철곰탱이 2024. 4. 18. 02:34

 

이번에 프로젝트에서 DTO를 적용하면서 Codable에 대해 이해하게 되었다.

그래서 이해한 걸 바탕으로 정리 해보려고 한다!!

 

json이 뭐야??

 

 

json의 정의는 아래와 같다.

 

JSON(JavaScript Object Notation)은 "키-값 쌍"으로 이루어진 데이터 오브젝트를 전달하기 위해 인간이 읽을 수 있는 텍스트를 사용하는 개방형 표준 포맷이다.

 

프로젝트를 진행할 때 api 요청과 응답 처리를 거의 밥먹듯이 하게 되는데 여기서 json 형식의 데이터를 다루는 과정을 거친다.

요즘은 거의 대부분 API 호출로 json 형식의 데이터를 받기 때문에 json 데이터를 다루는 것은 필수라고 생각한다.

 

 

 

🔎 Codable protocol

 

 

CodableDecodable와 Encodable 프로토콜의 결합이다. 

 

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

 

Decodable protocolEncodable protocol 각각 디코딩과 인코딩을 가능하게 하는 protocol이며 Codable 타입을 준수하는 데이터는 JSONDecoder, JSONEncoder를 통해 데이터를 디코딩, 인코딩 할 수 있다.

 

struct Person: Codable {
    var name: String
    var age: Int
}

 

이렇게 Codable을 준수하는 객체는 DecodableEncodable 프로토콜을 사용할 수 있다. 즉, 인코딩과 디코딩 모두 가능하다.

물론 Decodable만 준수하는 객체, Encodable만 준수하는 객체로 만들 수 있다.

 

이제 디코딩과 인코딩하는 법을 알아보자!!

 

1️⃣ Decodable

 

: API 응답 처리할 때 사용

 

디코딩 가능한 데이터를 나타내는 데 사용한다. JSON 또는 다른 포맷의 데이터를 객체로 변환할 수 있다.

즉, 받아온 JSON 타입을 Swift 타입으로 변환한다고 할 수 있다.

 

Decodable을 준수하는 객체는 decode()로 구현해야 한다.

 

struct Person: Decodable {
    var name: String
    var age: Int
}

 

Person 구조체는 Decodable 프로토콜을 준수하도록 한다.

 

// Decoding (Data -> Object)
let jsonString = """
{
    "name": "Bob",
    "age": 25
}
"""

 

만약 json타입을 위와 같이 받아온다고 가정해보자

 

let jsonData = jsonString.data(using: .utf8)!
do {
    let decoder = JSONDecoder()
    let decodedPerson = try decoder.decode(Person.self, from: jsonData)
    print(decodedPerson) // Person(name: "Bob", age: 25)
} catch {
    print("Decoding failed: \(error.localizedDescription)")
}

 

위의 코드를 하나씩 이해해보자.

let jsonData = jsonString.data(using: .utf8)!

 

.utf8으로 인코딩하여 읽을 수 있는 String으로 변환한다.

 

 

JSONEncoder 인스턴스 생성하여 JSON 형식의 데이터를 Swift 객체로 디코딩하는 데 사용한다.

 

let decodedPerson = try decoder.decode(Person.self, from: jsonData)

 

decode(_: _:) 메서드를 호출하여 JSON 데이터를 Person 구조체의 인스턴스로 디코딩한다.

try 키워드로 감싸여있어 디코딩 과정에서 발생하는 에러를 처리할 수 있다.

 

성공했다면 디코딩된 Person 객체 출력
디코딩 과정에서 오류가 발생했다면 catch 블록으로 이동하여 에러 메시지 출력

 

 

2️⃣ Encodable

 

: API 요청 보낼 때 사용

 

인코딩 가능한 데이터를 나타내는 데 사용한다. 객체를 JSON 또는 다른 포맷으로 변환할 때 사용할 수 있다.

즉, Swift 타입을 JSON 형태로 변환한다고 할 수 있다.

 

Encodable을 준수하는 객체는 encode()로 구현해야 한다.

 

struct Person: Encodable {
    var name: String
    var age: Int
}

 

Person 구조체는 Encodable 프로토콜을 준수하도록 한다. 

 

// Encoding (Object -> Data)
let person = Person(name: "Alice", age: 30)
do {
    let encoder = JSONEncoder()
    let jsonData = try encoder.encode(person)
    let jsonString = String(data: jsonData, encoding: .utf8)
    print(jsonString) // {"name":"Alice","age":30}
} catch {
    print("Encoding failed: \(error.localizedDescription)")
}

 

위의 코드를 하나씩 이해해보자.

 

let person = Person(name: "Alice", age: 30)

 

먼저 Person 객체를 생성한다.

 

 

JSONEncoder는 Swift객체를 JSON 형식의 데이터로 인코딩하는 데 사용된다.

 

let jsonData = try encoder.encode(person)

 

encode(_:) 메서드를 호출하여 Person 객체를 JSON 데이터로 인코딩한다. 이 과정에서 try를 사용하므로, 인코딩 과정에서 발생할 수 있는 에러를 처리할 수 있다. 만약 인코딩에 실패하면 catch 블록으로 이동하여 에러메시지를 출력한다.

 

let jsonString = String(data: jsonData, encoding: .utf8)

 

String(data: encoding:) 메서드를 사용하여 JSON 데이터를 .utf8 인코딩된 문자열로 반환한다.

 

성공했다면 인코딩된 데이터 출력
인코딩 과정에서 오류가 발생했다면 catch 블록으로 이동하여 에러 메시지 출력