API는 'The Movie Database' 를 사용했습니다.
지금까지 API 통신할 때는 서버에서 보내는 JSON 데이터 모두 같은 변수명과 타입으로 받아야 디코딩 된다고 알고 있었다.
그러나, CodingKey를 사용하면, 원하는 데이터를 원하는 변수명으로 바꾸어 디코딩 가능하다는 것을 배웠다.
API - JSON 객체
"page": 1,
"results": [
{
"adult": false,
"backdrop_path": "/9faGSFi5jam6pDWGNd0p8JcJgXQ.jpg",
"genre_ids": [
18,
80
],
"id": 1396,
"origin_country": [
"US"
],
"original_language": "en",
"original_name": "Breaking Bad",
"overview": "2008년 1월 AMC에서 방영을 시작한 범죄 스릴러. Breaking Bad는 막가기를 뜻하는 미국 남부 지방의 속어이다. 한때 노벨화학상까지 바라 볼 정도로 뛰어난 과학자였던 고등학교 화학 교사 월터 화이트는 자신의 50세 생일 날에 폐암 3기 진단을 받는다. 어느 날 동서와 함께 마약 단속 현장을 참관한 그는 현장에서 달아나는 옛 제자 제시를 발견한다. 뇌성마비에 걸린 고등학생 아들과 임신한 아내를 위해 제시에게 동업을 제의한 월터는 자신의 화학지식을 이용해 전례없는 고순도 고품질의 메스암페타민을 제조한다.",
"popularity": 511.117,
"poster_path": "/ztkUQFLlC19CCMYHW9o1zWhJRNq.jpg",
"first_air_date": "2008-01-20",
"name": "브레이킹 배드",
"vote_average": 8.9,
"vote_count": 13954
},
...
TV 구조체 정의
- Decodable 객체 정의
- JSON 객체를 모두 받아오는 것이 아닌 원하는 데이터만 다른 변수명으로 받을 계획
struct TV: Decodable {
let name: String
let overview: String
let posterURL: String
let vote: String
let firstAirDate: String
CodingKeys 열거형
- 열거형은 JSON 키와 Swift 속성 간의 매핑을 정의
- 열거형을 사용하여, JSON 키의 이름을 카멜케이스로 변수명 변경
- JSON의 키와 Swift 속성 이름이 동일하지 않을 때 사용
- JSON 키
- name
- overview
- poster_path
- vote_average
- vote_count
- first_air_date
private enum CodingKeys: String, CodingKey {
case name
case overview
case posterPath = "poster_path"
case voteAverage = "vote_average"
case voteCount = "vote_count"
case firstAirDate = "first_air_date"
}
초기화 메서드 init()
- init(from decoder : any Decoder) 메서드
- Decodable 프로토콜을 준수하기 위해 구현된 초기화 메서드
- JSON 데이터를 파싱하여 TV 객체의 속성에 값을 할당
init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
overview = try container.decode(String.self, forKey: .overview)
let path = try container.decode(String.self, forKey: .posterPath)
posterURL = "<https://image.tmdb.org/t/p/w500/\\(path)>"
let voteAverage = try container.decode(String.self, forKey: .voteAverage)
let voteCount = try container.decode(String.self, forKey: .voteCount)
vote = "\\(voteAverage) (\\(voteCount))"
firstAirDate = try container.decode(String.self, forKey: .firstAirDate)
}
디코더 과정 상세 설명
- 디코더 컨테이너 생성
- decoder.container(keyedBy : CodingKeys.self)를 사용하여 JSON 데이터의 상위 컨테이너를 생성 함
- 개별 속성 디코딩
- name과 overview는 JSON 데이터에서 동일한 이름의 키를 사용하여 직접 디코딩 됨
- posterPath는 JSON의 poster_path 키에서 값을 가져와 posterURL에 할당하기 전에 URL 형식으로 변환
- voteAverage, voteCount는 각각 vote_average, vote_count 키에서 값을 가져와 vote 문자열을 조합함
- firstAirDate는 first_air_date 키에서 값을 가져와 firstAirDate에 할당함
throws
- 해당 메서드가 오류를 던질 수 있음을 나타냄
- 메서드 내부에서 오류가 발생할 가능성이 있는 코드를 작성할 때 사용
- 디코딩 과정에서 JSON 데이터가 예상과 다르거나 형식이 맞지 않으면 오류가 발생하기 때문에, 이러한 오류를 호출한 코드에서 처리할 수 있도록 throws를 사용
try
- 오류를 던질 수 있는(throwing)함수를 호출할 때 사용됨
- try를 사용하면 호출된 함수가 오류를 던질 수 있으며, 오류가 발생할 경우 호출된 코드에서 이를 처리해야 함
- 디코딩 과정에서 try를 하는 이유는 decode 메서드가 오류를 던질 수 있기 때문
- 만약 오류가 발생하면 그 다음 로직은 실행되지 않고 즉시 오류가 던져짐
- 오류가 던져지면 오류는 호출 스택을 타고 올라가며 이를 처리할 수 있는 ‘catch’ 블록을 찾음
try 오류 처리 메커니즘
- 호출한 함수로 오류를 전달
- 오류가 발생한 함수가 throws를 사용하여 오류를 던질 수 있도록 선언되어있다면, 오류는 호출한 함수로 전달됨
- do-catch 블록에서 처리 : do-catch 블록을 사용하여 오류 처리
let jsonData = """
{
"name": "Sample TV Show",
"overview": "This is a sample overview.",
"poster_path": "/sample.jpg",
"vote_average": 8.9,
"vote_count": 237,
"first_air_date": "2023-09-29"
}
""".data(using: .utf8)!
do {
let decoder = JSONDecoder()
let tvShow = try decoder.decode(TV.self, from: jsonData)
print("Successfully decoded TV show: \\(tvShow)")
} catch {
print("Failed to decode TV show: \\(error)")
}
타입 자체를 나타내기 위한 ‘self’
- CodingKeys.self, String.self는 해당 타입 자체를 참조하는 데 사용됨
- 타입의 인스턴스가 아닌 타입 그 자체를 의미함
- 이를 통해 타입을 의도하고 있음을 알 수 있음
CodingKeys.self
- CodingKeys는 JSON 키를 Swift 속성과 매핑하는 열거형
- CodingKeys.self는 이 열거형 타입 자체를 참조함
- CodingKeys.self는 CodingKeys 타입의 메타타입을 의미
‘self’를 사용하지 않으면 발생하는 오류
- ‘self’를 사용하지 않으면 Swift 컴파일러는 타입의 인스턴스를 기대하게 됨
- 그러나 우리가 의도한 것은 인스턴스가 아니라 타입 그 자체
- self를 붙여서 타입 그 자체를 참조하고 있다는 것을 명확히 해야 함
'Swift' 카테고리의 다른 글
Swift - UILabel 일부 폰트 변경 (2) | 2024.10.01 |
---|---|
Swift - UIButton - Image, Title 위치 설정 (1) | 2024.09.30 |
Swift - Xcode 프로젝트 생성 (0) | 2024.06.24 |
Swift - 10. 에러 핸들링 (0) | 2024.01.06 |
Swift - 9. 배열과 딕셔너리 (1) | 2024.01.06 |