내일배움캠프 iOS

UIKit) TIL # 43 팀 프로젝트 - 영화상영정보 앱, 메인뷰 추가작업

yjuni22 2024. 12. 18. 22:11

메인뷰 API 연결 및 셀 데이터 관련 구현

 

메인 컬렉션뷰를 팀원분이 작업해 주시고

메인 뷰에서 API를 통해 받아온 데이터를
컬렉션뷰의 셀 클릭시 
내 담당뷰인 디테일 뷰로 전달받기 위한 과정을 메인뷰 담당 팀원과 함께 진행하였다.

 

메인뷰 API 데이터 받아오기

미리 만들어둔 NetworkManager를 통해 API 통신을 하여 데이터를 받아왔다.

  private func fetchNowPlayingMovies() {
        networkManager.fetchDataByAlamofire(path: .nowPlaying) { [weak self] (result: Result<MovieData, AFError>) in
            guard let self else { return }
            switch result {
            case .success(let movieData):
                self.nowPlayingMovies = movieData.results
                DispatchQueue.main.async {
                    self.collectionView.reloadData()
                }
            case .failure(let error):
                print("데이터 불러오기 실패: \(error.localizedDescription)")
            }
        }
    }

 

받아온 데이터는 CollectionViewDataSource 에서 cellForItemAt 을 통해
컬렉션뷰의 셀로 들어간다.

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MovieCell.identifier, for: indexPath) as? MovieCell else {
            return UICollectionViewCell()
        }
        
        switch indexPath.section {
        case 0:
            cell.movieData = popularMovies[indexPath.item]
        case 1:
            cell.movieData = nowPlayingMovies[indexPath.item]
        case 2:
            cell.movieData = upcomingMovies[indexPath.item]
        default:
            return UICollectionViewCell()
        }
        return cell
    }


컬렉션뷰의 경우 섹션별로 다른 데이터를 받아오도록 구현해놨기 때문에

각각의 섹션에 맞는 데이터를 셀에 할당한다.

이후 셀에서 받아온 데이터를 통해 텍스트와 이미지를 적용시킨다.

 

 var movieData: Movie? {
        didSet {
            guard let movie = movieData else { return }
            titleLabel.text = movie.title
            
            /// 이미지 path값을 url로
            if let posterPath = movie.posterPath {
                self.imageURL = MovieImage.movieImageURL(size: 200, posterPath: posterPath)
            }
        }
    }
    
    /// 변환된 Url 로 load
    var imageURL: String? {
        didSet {
            loadImage()
        }
    }

 

CellForItemAt 에서는 데이터 형태로 전달하고

Cell 에서 didSet을 통해 데이터를 적용시킨다.

이미지의 경우 URL 만 넘긴 후 셀에서 이미지를 로드한다.
(이미지를 cellForRowAt에 직접 로드하도록 하면 빠르게 스크롤시 = 셀의 재사용시 이미지가 겹치는 현상이 발생할 수 있음)

 

// URL로 이미지 로드
    private func loadImage() {
        
        guard let urlString = self.imageURL, let url = URL(string: urlString) else { return }
        
        DispatchQueue.global().async {
            guard let data = try? Data(contentsOf: url) else { return }
            
            // url이 바뀔 가능성 제거
            guard urlString == url.absoluteString else { return }
            
            DispatchQueue.main.async {
                self.posterImageView.image = UIImage(data: data)
            }
        }
    }

 

셀 선택 시 데이터 넘기기

extension MovieListViewController: UICollectionViewDelegate {
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        
        let detailVC = DetailViewController()
        
        switch indexPath.section {
        case 0:
            detailVC.movieData = popularMovies[indexPath.item]
        case 1:
            detailVC.movieData = nowPlayingMovies[indexPath.item]
        case 2:
            detailVC.movieData = upcomingMovies[indexPath.item]
        default:
            return
        }
        navigationController?.pushViewController(detailVC, animated: true)
    }
}

 

각각의 섹션에서 셀을 클릭했을 때 
섹션 안에 각각 다른 데이터가 들어가 있기 때문에 다음과 같이
섹션별로 나누어 데이터가 전달되도록 구현하였다.