❌ 문제: DetailViewController(상세 페이지)내 유사 영화 또는 TV를 눌러 DetailViewController로 이동할 때 장르가 보이지 않음
🎯 문제 분석
현재 HomeViewController에서 fetchMediaData()를 실행할 때만 장르 정보를 변환하고,
이 데이터를 static var homeSections에 저장해서 다른 뷰컨트롤러(DetailViewController)에서도 접근하도록 했지만,
- DetailViewController -> DetailViewController로 이동할 때는 HomeViewController가 다시 실행되지 않으므로,
- 새로운 데이터(유사 영화, TV 정보)의 장르 정보는 homeSections에 포함되지 않아서 getGenresFromHomeSection(for:)가 정상적으로 동작하지 않음
// MARK: - Functions
/// API에서 데이터를 받아와 homeSections에 저장
private func fetchMediaData() {
Task {
do {
// 1. 트렌딩 영화 목록 가져오기
var trendingMovies = try await NetworkManager.shared.getTrendingMovies()
//dump(trendingMovies)
// 2. 영화 장르 목록 가져오기
let movieGenres = 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
movieGenres.first(where: { $0.id == genreId })?.name
}
// 장르 이름 저장
trendingMovies[i].genreNames = matchedGenres
}
// 트렌딩 TV 목록 가져오기
var trendingTVs = try await NetworkManager.shared.getTrendingTVs()
// 트렌딩 TV 장르 목록 가져오기
let tvGenres = try await NetworkManager.shared.getTVGenre()
// 각 TV의 genreIds를 genreNames로 변환
for i in 0..<trendingTVs.count {
let tv = trendingTVs[i]
let matchedGenres = tv.genreIDS.compactMap { genreId in
if let genre = tvGenres.first(where: { $0.id == genreId }) {
return genreTranslation[genre.name] ?? genre.name // ✅ 한글 변환 적용
}
return nil
}
// 장르 이름 저장
trendingTVs[i].genreNames = matchedGenres
}
// 트렌딩 배우 목록 가져오기
let trendingPeoples = try await NetworkManager.shared.getTrendingPeoples()
// 트렌딩 all 목록에서 랜덤 1개의 정보 가져오기
let trendingAll = try await NetworkManager.shared.getRandomTrendingMovie()
// HomeViewController의 데이터 업데이트
HomeViewController.homeSections = [
.trendingMovies(trendingMovies),
.trendingTVs(trendingTVs),
//.trendingPeoples(trendingPeoples),
]
DispatchQueue.main.async {
self.homeFeedTableView.reloadData()
self.headerView?.configure(trendingAll) // ✅ HeaderView 업데이트
}
} catch {
print("Failed to fetch data: \(error)")
}
}
}
✅ 해결 방법: HomeViewController에서 장르 데이터를 static 프로퍼티로 저장
🔹 해결 원리
- HomeViewController가 실행될 때 영화 장르(movieGenres)와 TV 장르(tvGenres)를 별도의 static 변수로 저장
- DetailViewController에서는 HomeViewController의 static 변수에 접근하여 genreIDS에 해당하는 name을 찾을 수 있도록 변경
- 이렇게 하면 DetailViewController -> DetailViewController로 이동할 때도 항상 동일한 장르 데이터를 활용할 수 있음.
✅ 코드 변경
1️⃣ HomeViewController에서 static 프로퍼티 추가
class HomeViewController: UIViewController {
// ✅ 영화 및 TV 장르를 저장할 `static` 프로퍼티 추가
static var movieGenres: [Genre] = []
static var tvGenres: [Genre] = []
static var homeSections: [HomeSection] = []
private var homeHeaderRandomItem: MovieResult?
private var homeFeedTableSection: [String] = ["Trending Movie", "Trending TV", "Trending People"]
// MARK: - Functions
/// API에서 데이터를 받아와 homeSections에 저장
private func fetchMediaData() {
Task {
do {
// 1. 트렌딩 영화 목록 가져오기
var trendingMovies = try await NetworkManager.shared.getTrendingMovies()
//dump(trendingMovies)
// 2. 영화 장르 목록 가져오기
let movieGenres = try await NetworkManager.shared.getMovieGenre()
// ✅ 영화 장르 저장
HomeViewController.movieGenres = movieGenres
// 3. 각 영화의 genreIds를 genreNames로 변환
for i in 0..<trendingMovies.count {
let movie = trendingMovies[i]
let matchedGenres = movie.genreIDS.compactMap { genreId in
movieGenres.first(where: { $0.id == genreId })?.name
}
// 장르 이름 저장
trendingMovies[i].genreNames = matchedGenres
}
// 트렌딩 TV 목록 가져오기
var trendingTVs = try await NetworkManager.shared.getTrendingTVs()
// 트렌딩 TV 장르 목록 가져오기
let tvGenres = try await NetworkManager.shared.getTVGenre()
// ✅ TV 장르 저장
HomeViewController.tvGenres = tvGenres
// 각 TV의 genreIds를 genreNames로 변환
for i in 0..<trendingTVs.count {
let tv = trendingTVs[i]
let matchedGenres = tv.genreIDS.compactMap { genreId in
if let genre = tvGenres.first(where: { $0.id == genreId }) {
return genreTranslation[genre.name] ?? genre.name // ✅ 한글 변환 적용
}
return nil
}
// 장르 이름 저장
trendingTVs[i].genreNames = matchedGenres
}
// 트렌딩 배우 목록 가져오기
//let trendingPeoples = try await NetworkManager.shared.getTrendingPeoples()
// 트렌딩 all 목록에서 랜덤 1개의 정보 가져오기
let trendingAll = try await NetworkManager.shared.getRandomTrendingMovie()
// HomeViewController의 데이터 업데이트
HomeViewController.homeSections = [
.trendingMovies(trendingMovies),
.trendingTVs(trendingTVs),
//.trendingPeoples(trendingPeoples),
]
DispatchQueue.main.async {
self.homeFeedTableView.reloadData()
self.headerView?.configure(trendingAll) // ✅ HeaderView 업데이트
}
} catch {
print("Failed to fetch data: \(error)")
}
}
}
}
✅ 변경된 점:
- HomeViewController.movieGenres와 HomeViewController.tvGenres를 static 변수로 추가하여 API에서 받아온 장르 정보를 저장
- 이후 DetailViewController에서도 해당 장르 정보를 static 변수에서 바로 가져올 수 있음
2️⃣ DetailViewController에서 getGenresFromHomeSection(for:) 수정
🔹 기존 코드 (잘못된 방식)
private func getGenresFromHomeSection(for contentID: Int) -> [String] {
for section in HomeViewController.homeSections {
switch section {
case .trendingMovies(let movies):
if let movie = movies.first(where: { $0.id == contentID }) {
return movie.genreNames ?? [] // ✅ 영화의 장르 변환
}
case .trendingTVs(let tv):
if let tv = tv.first(where: { $0.id == contentID}) {
return tv.genreNames ?? [] // ✅ tv의 장르 변환
}
}
}
return []
}
🚨 문제점:
- HomeViewController.homeSections에 저장된 데이터가 업데이트되지 않으면 DetailViewController에서 올바른 장르를 가져오지 못함
✅ 변경 코드 (올바른 방식)
private func getGenresFromHomeSection(for genreIDs: [Int], contentType: ContentType) -> [String] {
switch contentType {
case .movie:
return genreIDs.compactMap { genreID in
HomeViewController.movieGenres.first { $0.id == genreID }?.name
}
case .tv:
return genreIDs.compactMap { genreID in
HomeViewController.tvGenres.first { $0.id == genreID }?.name
}
case .people:
return []
}
}
✅ 변경된 점:
- HomeViewController.movieGenres와 HomeViewController.tvGenres에서 직접 장르를 찾아서 반환하도록 변경
- contentID를 기반으로 찾는 방식이 아니라, API에서 받은 genreIDs를 기반으로 변환하도록 수정
- 이제 DetailViewController에서 getGenresFromHomeSection(for genreIDs: [Int], contentType: ContentType) -> [String] 를 사용하면 항상 최신 장르 데이터를 가져올 수 있음! 🚀
3️⃣ fetchContentDetail()에서 getGenresFromHomeSection(for:) 대신 getGenresFromHomeSection(for genreIDs: [Int], contentType: ContentType) 사용
/// init으로 받아온 데이터를 통해 API 요청
private func fetchContentDetail() {
Task {
do {
// ✅ switch 문에서 데이터를 fetchedDetail 변수에 저장하고, 이후 한 번만 UI 업데이트를 수행
var fetchedDetail: ContentDetail?
var fetchedGenres: [String] = [] // 장르 저장 변수
var castingList: TopBilledCastInfoWelcome? // 출연진 목록 저장
var videoInfo: VideoInfoWelcome?
var posterInfo: PosterInfoWelcome?
var fetchedSimilarInfo: HomeSection?
switch contentType {
case .movie:
let movieDetail = try await NetworkManager.shared.getMovieDetailInfo(movieID: contentID)
fetchedDetail = .movie(movieDetail)
// ✅ 장르 [Int] 타입으로 변환
let genres = movieDetail.genres.map { $0.id }
// ✅ fetchedGenres에 장르 저장
fetchedGenres = getGenresFromHomeSection(for: genres, contentType: .movie)
castingList = try await NetworkManager.shared.getMovieCastInfo(contentID: contentID)
videoInfo = try await NetworkManager.shared.getMovieVideoInfo(contentID: contentID)
posterInfo = try await NetworkManager.shared.getMoviePosterInfo(contentID: contentID)
let movieSimiliar = try await NetworkManager.shared.getMovieSimilarInfo(contentID: contentID)
fetchedSimilarInfo = .trendingMovies(movieSimiliar)
case .tv:
let tvDetail = try await NetworkManager.shared.getTVDetailInfo(tvID: contentID)
fetchedDetail = .tv(tvDetail)
// ✅ 장르 [Int] 타입으로 변환
let genres = tvDetail.genres.map { $0.id }
// ✅ fetchedGenres에 장르 저장
fetchedGenres = getGenresFromHomeSection(for: genres, contentType: .tv)
castingList = try await NetworkManager.shared.getTVCastInfo(contentID: contentID)
videoInfo = try await NetworkManager.shared.getTvVideoInfo(contentID: contentID)
posterInfo = try await NetworkManager.shared.getTvPosterInfo(contentID: contentID)
let tvSimiliar = try await NetworkManager.shared.getTVSimilarInfo(contentID: contentID)
fetchedSimilarInfo = .trendingTVs(tvSimiliar)
case .people: break
//let peopleDetail = try await NetworkManager.shared.getPeopleDetailInfo(peopleID: contentID)
//fetchedDetail = .people(peopleDetail)
//fetchedGenres = getGenresFromHomeSection(for: contentID)
}
'Project > MovieClip' 카테고리의 다른 글
🤔 배우 프로필의 소개 부분 "더보기" "접기" 기능 구현 (1) | 2025.02.14 |
---|---|
배우의 소셜 미디어 계정을 가져오는 방법 🤔 (0) | 2025.02.14 |
✅ 영화 평점 기능 구현 (0) | 2025.02.13 |
thumnailImageView에서 .video 와 .poster 분기 처리하기 (0) | 2025.02.12 |
📌 컬렉션 뷰에서 .video 아이템 클릭 시 YouTube 영상 재생하기 (0) | 2025.02.12 |