본문 바로가기

Project/MovieClip

❌ 문제 해결: 상세페이지에서 유사 영화 정보의 상세페이지 이동할 때 장르가 보이지 않음

 

❌ 문제: 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 프로퍼티로 저장

🔹 해결 원리

  1. HomeViewController가 실행될 때 영화 장르(movieGenres)TV 장르(tvGenres)별도의 static 변수로 저장
  2. DetailViewController에서는 HomeViewController의 static 변수에 접근하여 genreIDS에 해당하는 name을 찾을 수 있도록 변경
  3. 이렇게 하면 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)
                }