📌 해결해야 할 문제
1️⃣ 영화 목록 내 genre_ids의 값을 받아옴
{
"page": 1,
"results": [
{
...
"genre_ids": [
27,
53
],
...
},
2️⃣ 장르의 값을 TMDB API를 통해 받아옴
{
"genres": [
{
"id": 27,
"name": "공포"
},
...
},
{
"id": 53,
"name": "스릴러"
}
]
}
3️⃣ genre_Ids의 값을 TMDB API를 통해 받아온 genres에서 찾아 name을 반환
🔷 27, 53 ➡️ "공포 / 스릴러" 반환
📌 해결해야 할 문제
- fetchMediaData()에서 getTrendingMovies()를 호출하여 영화 목록을 가져옴.
- 각 영화의 genre_ids를 이용해 getMovieGenre()를 호출하고 해당 ID와 매칭되는 장르 이름을 찾음.
- 각 영화에 genreNames 필드를 추가하여 CollectionViewCell에서 사용할 수 있도록 함.
- CollectionViewCell에서 genreNames를 스릴러 / 액션 / 공포 형식으로 표시.
🚀 해결 방법
1️⃣ fetchMediaData()에서 getTrendingMovies()를 호출한 후, getMovieGenre()를 실행하여 장르 데이터 가져오기
2️⃣ 각 영화의 genre_ids와 getMovieGenre()에서 가져온 장르 목록을 비교하여 매칭되는 장르 이름을 저장
3️⃣ 최종적으로 MovieResult에 genreNames: [String] 추가 후, CollectionViewCell에서 활용
🔹 Step 1: MovieResult에 genreNames 추가
struct MovieResult: Codable {
let id: Int
let title: String
let genreIds: [Int]
let posterPath: String?
let releaseDate: String
let voteAverage: Double
var genreNames: [String]? // ✅ 장르 이름을 저장하는 필드 추가
}
🔹 Step 2: fetchMediaData()에서 getMovieGenre() 호출하여 장르 이름 매핑
✅ 각 영화의 genre_ids와 장르 목록을 비교하여 genreNames에 저장하는 과정 추가
✅ 이제 MovieResult에 genreNames가 포함되므로, CollectionViewCell에서 사용 가능
private func fetchMediaData() {
Task {
do {
// ✅ 1. 영화 목록 가져오기
var trendingMovies = try await NetworkManager.shared.getTrendingMovies()
// ✅ 2. 장르 목록 가져오기
let genres = try await NetworkManager.shared.getMovieGenre()
// ✅ 3. 각 영화의 genreIds를 genreNames로 변환
for i in 0..<trendingMovies.count {
let movie = trendingMovies[i]
let matchedGenres = movie.genreIds.compactMap { genreId in
genres.first(where: { $0.id == genreId })?.name
}
trendingMovies[i].genreNames = matchedGenres // ✅ 장르 이름 저장
}
// ✅ 4. HomeViewController의 데이터 업데이트
HomeViewController.homeSections = [
.trendingMovies(trendingMovies)
]
DispatchQueue.main.async {
self.homeFeedTableView.reloadData()
}
} catch {
print("Failed to fetch data: \(error)")
}
}
}
🔹 Step 3: CollectionViewCell에서 장르 표시 (/ 구분)
✅ joined(separator: " / ")를 사용하여 장르를 "스릴러 / 액션 / 공포" 형식으로 변환
✅ 장르 정보가 없을 경우 "장르 없음"을 표시하여 UI 안정성 확보
func configureCollectionView(with movie: MovieResult) {
titleLabel.text = movie.title
releasedDateLabel.text = formatDateString(movie.releaseDate)
let score = (movie.voteAverage)
if score != 0 {
scoreLabel.configure(with: Int(score) * 10)
} else {
scoreLabel.configure(with: 100)
}
let posterPath = movie.posterPath
guard let url = URL(string: "https://image.tmdb.org/t/p/w500/\(posterPath)") else { return }
posterImageView.sd_setImage(with: url, completed: nil)
// ✅ 장르를 " / "로 구분하여 표시
if let genres = movie.genreNames, !genres.isEmpty {
genreLabel.text = genres.joined(separator: " / ") // ✅ "스릴러 / 액션 / 공포" 형식으로 표시
} else {
genreLabel.text = "장르 없음" // ✅ 장르 정보가 없을 경우 기본값 설정
}
}
🚀 최종 정리
✈️ compactMap을 이용한 genreIds → genreNames 변환 이해하기
// 각 영화의 genreIds를 genreNames로 변환
for i in 0..<trendingMovies.count {
let movie = trendingMovies[i]
let matchedGenres = movie.genreIds.compactMap { genreId in
genres.first(where: { $0.id == genreId })?.name
}
trendingMovies[i].genreNames = matchedGenres // ✅ 장르 이름 저장
}
✅ 위 코드의 역할
- movie.genreIds는 해당 영화의 장르 ID 배열 (예: [27, 53])
- genres는 모든 장르 목록 (id: name 형태의 배열)
- compactMap {}을 이용해 해당 영화의 genre_ids를 genreNames로 변환
🚀 compactMap 동작 방식
1️⃣ 기존 데이터 구조
✅ trendingMovies 예제
let trendingMovies = [
MovieResult(id: 1, title: "영화 A", genreIds: [27, 53], posterPath: "", releaseDate: "", voteAverage: 7.5),
MovieResult(id: 2, title: "영화 B", genreIds: [28, 12], posterPath: "", releaseDate: "", voteAverage: 8.2)
]
✅ genres 데이터 예제 (getMovieGenre() 결과)
let genres = [
Genre(id: 27, name: "공포"),
Genre(id: 53, name: "스릴러"),
Genre(id: 28, name: "액션"),
Genre(id: 12, name: "모험")
]
2️⃣ compactMap 동작 과정
🎯 movie.genreIds에 대해 genres에서 매칭되는 name을 찾는 과정
let movie = trendingMovies[0] // "영화 A"
let matchedGenres = movie.genreIds.compactMap { genreId in
genres.first(where: { $0.id == genreId })?.name
}
movie.genreIds (입력) | geres 에서 매칭되는 name |
[27, 53] | ["공포", "스릴러"] |
📌 compactMap이 하는 일
✅ compactMap을 한 줄씩 설명하면:
movie.genreIds.compactMap { genreId in
genres.first(where: { $0.id == genreId })?.name
}
1️⃣ movie.genreIds 리스트를 순회하면서, 각 genreId에 대해
2️⃣ genres.first(where: { $0.id == genreId })을 사용하여 해당하는 장르를 찾음
3️⃣ ?.name을 통해 name만 가져옴
4️⃣ compactMap은 nil을 제거하고 유효한 값만 남김
🚀 compactMap을 for 문으로 풀어쓰기
var matchedGenres: [String] = []
for genreId in movie.genreIds {
if let genre = genres.first(where: { $0.id == genreId }) {
matchedGenres.append(genre.name)
}
}
🚕 날짜형식 변경
https://explorer89.tistory.com/320
날짜 형식 변환
📌 날짜 형식 변환 (2025-2-11 → 2월 11일 2025년)🔷 TMDB API를 통해 받아오는 데이터 중 released_date의 날자 형식을 변경{ "page": 1, "results": [ { ... "popularity": 396.136, "release_date": "2025-01-15", ... }, ... movie.re
explorer89.tistory.com
'Project > MovieClip' 카테고리의 다른 글
테이블의 섹션 별로 다르게 UI 구성 (0) | 2025.02.07 |
---|---|
영어 장르 이름을 한글로 표시하기 (0) | 2025.02.07 |
테이블 섹션 별 데이터 모델 사용 (0) | 2025.02.06 |
에러 발생 - 데이터 모델 누락 (0) | 2025.02.05 |
TMDB API 데이터를 가져오는 방식 - async / await 방식 채택 (0) | 2025.02.05 |