FiveMovies Project (2)

ulls12·2024년 1월 19일
0

Swift TIL

목록 보기
33/60

MovieList View 완성도 높히기

어제까지의 작업량은 분명 초반에 바로 데이터를 받아와 화면에 구현하지 못했고 각각의 세그먼트를 클릭했을 때만 데이터를 불러왔다.
우선 기술적인 부분에선 해결점들을 구성했다.

1. Cell 개수 정하기

collectionview cell에 제약을 걸어주고 각각의 cell안에 있는 image와 label 간에 제약을 걸어준다. collectionview 내에서의 간격과 제약들을 코드로 추가적으로 구현한다.

//ViewController
	let flowLayout = UICollectionViewFlowLayout()
	searchCollectionView.collectionViewLayout = flowLayout

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let cellWidth = (collectionView.bounds.width - 10) / 2
        let cellHeight = collectionView.bounds.height / 3
        
        return CGSize(width: cellWidth, height: cellHeight)
    }
    
//cell.swift
@IBOutlet weak var movieName: UILabel!
    @IBOutlet weak var movieImage: UIImageView!
    
    var movie: MovieData.Movie?
    
    func setCell(_ _movie: MovieData.Movie) {
        movie = _movie
        
        self.movieName.text = _movie.title
        self.movieName.sizeToFit()
        self.movieImage.contentMode = .scaleToFill
// 아래 코드들 ...

이렇게 설정하면 위에 보이는 이미지와 같이 cell 간의 간격이 가로행은 2개로 세로행은 3개로 총 한 화면에 6개로 구성이 된다

2. 빌드 시 바로 데이터 받아서 view에 호출해주기

가장 많이 고민했고, 가장 많이 헤멨던 부분이다. 우선 collectionview에 있는 cell들이 화면이 전환됨과 동시에 데이터들을 전송받아야한다.

//VC viewDidLoad()에 구현된 코드
MovieData.shared.getNowPlayingMovies(completion: { [weak self] in
            self?.displayCollectionView = MovieData.shared.nowPlayingMovies
            DispatchQueue.main.async {
                self?.movieCollectionView.reloadData()
            }
        })
//Data Class에 구현된 코드
    public func getNowPlayingMovies(completion: @escaping () -> Void) {
        
        //파일 형식과 API키를 정의한 헤더부
        let headers = [
            "accept": "application/json",
            "Authorization": "Bearer eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJmM2Q1ZTNlYWY2MGViNWY3Njg5YjhjMjIxNTYyMzlhNCIsInN1YiI6IjY1YTUwZDgwMWZiOTRmMDBjMDc0YTFhNyIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.4pi9VmylhkY94DoJk6s4Ol7txHjXcyonKy3PeI9ZdS8"
        ]
        
        //요청을 보낼 URL
        let url = URL(string: "https://api.themoviedb.org/3/movie/now_playing?language=ko-KR&page=1")!
        
        //URL에 요청
        var request = URLRequest(url: url, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
        
        //HTTP 메서드 설정
        request.httpMethod = "GET"
        
        //요청에 헤더부 추가
        request.allHTTPHeaderFields = headers
        
        let session = URLSession.shared
        let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) in
            
            //에러 처리
            if let error = error {
                print("Error fetching data: \(error)")
                return
            }
            
            //데이터 옵셔널 바인딩
            guard let data = data else {
                print("No data received")
                return
            }
            
            //데이터 처리
            do {
                let decoder = JSONDecoder()
                let result = try decoder.decode(Result.self, from: data)
                self.nowPlayingMovies = result.results
                completion()
                print ("현재상영작 데이터 세팅 완료")
            } catch {
                print("Error parsing JSON: \(error)")
            }
            
        })
        dataTask.resume()
    }

통신이나 비동기 처리를 하는 코드를 작성할 때, completion 클로저를 사용하고 @escaping이라는 탈출 클로저를 사용한다. 또한 shared라는 싱글톤 패턴을 적용하여 클래스에 직접 접근해서 쓸수 있도록 만들어준다.

앞으로 해야 할 일

  1. SearchView 만들기
  2. 화면 전환 간 데이터 전달 방식 생각하기
  3. Layout 설정하기
profile
I am 개발해요

0개의 댓글