프로젝트를 진행 중 하나의 코드 리뷰를 받았습니다.
해당 피드백을 본 후 모델을 생성할때도 그 용도에 맞게 프로토콜을 채택해야될 것 같다고 생각이 들었습니다
Swift에서 네트워크 통신이나 로컬 파일 저장을 하다 보면 흔하게 마주치는 프로토콜이 있습니다. 바로 Codable, 그리고 그를 구성하는 Encodable, Decodable입니다. 이 글에서는 Apple 공식 문서를 기반으로 이 프로토콜들의 의미와 차이점, 그리고 언제 어떤 걸 써야 할지 정리해보겠습니다.
Codable이란?
typealias Codable = Encodable & Decodable
Codable은 Swift가 제공하는 타입 에일리어스로, Encodable과 Decodable을 동시에 채택한 것을 의미합니다. 즉, 이 타입은 JSON, PropertyList 등 외부 표현으로 인코딩하고, 다시 객체로 디코딩할 수 있는 타입입니다.
애플 공식 문서
A type that can convert itself into and out of an external representation.
– Codable – Apple Developer Documentation
Encodable
Encodable은 객체를 외부 표현(예: JSON)으로 변환(인코딩) 할 수 있는 타입입니다.
struct Book: Encodable {
let title: String
let author: String
}
let book = Book(title: "Harry Potter", author: "J.K. Rowling")
let jsonData = try JSONEncoder().encode(book)
이 구조체는 JSONEncoder를 통해 쉽게 JSON 데이터로 변환할 수 있습니다.
Decodable
Decodable은 외부 표현(예: JSON)을 객체로 복원(디코딩) 할 수 있는 타입입니다.
struct Book: Decodable {
let title: String
let author: String
}
let json = """
{
"title": "Harry Potter",
"author": "J.K. Rowling"
}
""".data(using: .utf8)!
let book = try JSONDecoder().decode(Book.self, from: json)
왜 Codable이 아니라 Decodable만 쓸까?
객체가 오직 읽기 전용(서버 → 앱) 용도로만 사용될 경우, Decodable만 채택하는 것이 더 안전하고 설계 의도를 분명히 할 수 있습니다.
서버에서 받아오는 데이터 전용 모델이라면, 인코딩이 필요 없기 때문에 굳이 Encodable까지 포함된 Codable을 쓸 필요는 없습니다.
프로젝트도 동일하게 JSON 파일을 앱으로 디코딩만 하는 경우이기 때문에 Codable이 아닌 Encodable을 쓰면 된다.
struct Book: Decodable {
let title: String
let author: String
let pages: Int
let releaseDate: String
let dedication: String
let summary: String
let wiki: String
let chapters: [Chapter]
enum CodingKeys: String, CodingKey {
case title
case author
case pages
case releaseDate = "release_date"
case dedication
case summary
case wiki
case chapters
}
}
이렇게 하면, 실수로 인코딩(JSONEncoder().encode(...))을 시도할 경우 컴파일 에러가 발생해 코드의 안정성을 높일 수 있습니다.
Codable을 쓸 때 주의할 점
- JSONDecoder와 JSONEncoder는 자동으로 CodingKeys를 생성하지만, 커스텀 키 이름이 필요한 경우 CodingKeys enum을 정의해야 합니다.
- Optional, Array, Dictionary도 Codable을 자동 준수합니다 (단 내부 요소도 Codable이어야 함).
- 커스텀 타입 내에 Date, URL 같은 타입은 포맷 설정이 필요할 수 있습니다.
결론
인코딩만 필요함 | Encodable |
디코딩만 필요함 | Decodable |
양방향 모두 필요 | Codable (= Encodable + Decodable) |
작고 가벼운 타입은 그냥 Codable로 쓰는 것도 편하지만, 명확한 역할 분리를 통해 설계를 더 견고하게 만들 수 있다는 점을 기억하자.
'iOS > Swift' 카테고리의 다른 글
[ Swift ] 비동기 처리와 DispatchQueue.main.async (0) | 2025.04.04 |
---|---|
[ Swift ] Swift 5.9 신기능: 복사 불가능한 타입 (Noncopyable Types) (0) | 2025.03.26 |
[ Swift ] ARC : Automatic Reference Counting (0) | 2025.03.25 |
[ Swift ] 접근 제어자 (0) | 2025.03.13 |
[ Swift ] 중첩 타입 (0) | 2025.03.13 |