카테고리 없음

Swift: Decode 시에 응답 데이터 변환하기

ragdoll-cat 2025. 3. 4. 21:47

 

 

안녕하세요. 

일반적으로 API 통신을 할 때, JSON 형식의 응답 데이터를 Data 타입에서 구조체로 미리 정의해 놓은 타입으로 변환하여 사용합니다. 

이 과정을 디코딩이라고 부르는데요, 단순히 변환하는 것 뿐만 아니라 필요한 데이터로 가공 및 변환을 동시에 수행해야 하는 경우가 있습니다.

이번 글에서는 Decodable을 활용하여 JSON 디코딩 과정에서 데이터를 변환하는 방법을 정리해보겠습니다.


1️⃣ 보통의 Decodable

struct PostByUser: Decodable {
  let title: String
  let body: String
}

Swift 구조체에 Decodable을 채택하면 Data 타입의 데이터를 해당 구조체로 디코딩할 수 있게 됩니다.

 

2️⃣ 매칭된 키 값 변경을 위한 CodingKeys 사용

만약 JSON에서 created_at, updated_at과 같은 값이 추가되었다면, 이러한 키를 그대로 쓰기엔 Swift의 camelCase 네이밍 규칙과 맞지 않죠. 이럴 때 CodingKeys를 활용하여 키 값을 변경할 수 있습니다.

struct PostByUser: Decodable {
  let title: String
  let body: String
  let createdAt: String
  let updatedAt: String
  
  enum CodingKeys: String, CodingKey {
    case title, body
    case createdAt = "created_at"
    case updatedAt = "updated_at"
  }
}

이제 created_at은 디코딩 과정에서 자동으로 createdAt으로, updated_at은 디코딩 과정에서 자동으로 updatedAt으로 변환됩니다.

 

3️⃣ 응답 데이터 변환하기

날짜를 추가한 것 까진 좋았는데, 응답 데이터가 이렇게 생겼다고 해봅시다.

{
  "title": "안녕하세요.",
  "body": "반갑습니다.",
  "created_at": "2025-03-04T00:56:51.295Z",
  "updated_at": "2025-03-04T00:56:51.295Z"
}

서버 측에서는 클라이언트가 어떤 포맷의 날짜를 사용할 것인지 알 수 없습니다.

그렇기 때문에 최대한 범용적이고 시스템이 처리하기에 가장 적합한 형식을 사용하고 있습니다. 이 값을 변환시켜봅시다.

 

변환 방법은 흔히 DateFormatter로 변환하는 방법과 같습니다.

응답으로 받은 String을 일단 Date 타입으로 변환하고, 변환시킬 dateFormat을 지정한 후 다시 String으로 변환합니다.

String -> Date -> String

 

struct PostByUser: Decodable {
  ...
  init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    // 변화 없음
    title = try container.decode(String.self, forKey: .title)
  	body = try container.decode(String.self, forKey: .body)
  
    let isoFormatter = ISO8601DateFormatter()
    let outputFormatter = DateFormatter()
    isoFormatter.formatOptions = [.withInternetDateTime, .withFullDate, .withDashSeparatorInDate, .withFractionalSeconds]
    outputFormatter.dateFormat = "yyyy.MM.dd"
  
    if let createdDate = dateFormatter.date(from: try container.decode(String.self, forKey: .createdAt)) {
      createdAt = outputFormatter.string(from: createdDate)
    } else {
      createdAt = ""
    }
        
    if let updatedDate = dateFormatter.date(from: try container.decode(String.self, forKey: .updatedAt)) {
      updatedAt = outputFormatter.string(from: updatedDate)
    } else {
      updatedAt = ""
    }
  }
}

Decoder를 통해서 인스턴스가 생성될 때, 보통의 키들은 그대로 넘어가고, 변환할 Date관련 값들은 dateFormatter를 거쳐 변환시킵니다.

이제 createdAt, updatedAt 2025-03-04T00:56:51.295Z 형태에서 2025.03.04로 변환됩니다.


4️⃣ 마무리

이번 글에서는 Swift의 Decodable을 활용하여 JSON 디코딩 과정에서 데이터를 변환하는 방법을 살펴보았습다. 핵심 내용을 정리하자면:

 CodingKeys를 활용하면 JSON 키와 Swift 속성 이름을 매핑할 수 있다.
 init(from decoder:)를 사용하면 디코딩 과정에서 데이터를 가공할 수 있다.

 

감사합니다! 🚀