Skip to content

Conversation

@wotjs020708
Copy link
Collaborator

구현 영상

Simulator.Screen.Recording.-.iPhone.13.mini.-.2025-12-17.at.22.11.13.mov

구현 내용

  • SwifUI 사용
  • 네트워크 통신 기본 URLSession + Combine 사용
  • PathModel을 이용한 뷰 관리

주요 코드

MovieService

enum NetworkError: Error {
    case invalidURL
    case invalidResponse
    case decodingError(Error)
}
  • 네트워크 에러 enum 타입으로 분류
return URLSession.shared.dataTaskPublisher(for: url)
            .mapError { _ in NetworkError.invalidResponse }
            .map(\.data)
            .decode(type: BoxOfficeResponse.self, decoder: JSONDecoder())
            .mapError { NetworkError.decodingError($0) }
            .map(\.boxOfficeResult.dailyBoxOfficeList)
            .receive(on: DispatchQueue.main)
            .eraseToAnyPublisher()
  • 고차 함수를 이용한 네트워크 통신 및 디코딩

MovieListViewModel

final class MovieListViewModel: ObservableObject {
    @Published var movies: [DailyBoxOffice] = []
    @Published var isLoading = false
    @Published var errorMessage: String?
    
    private let movieService = MovieService()
    private var cancellables = Set<AnyCancellable>()
    
    func fetchMovies() {
        isLoading = true
        errorMessage = nil
        
        movieService.fetchMovies()
            .sink { [weak self] completion in
                self?.isLoading = false
                if case .failure(let error) = completion {
                    self?.errorMessage = error.localizedDescription
                }
            } receiveValue: { [weak self] movies in
                self?.movies = movies
            }
            .store(in: &cancellables)
    }
}
  • @published를 활용하여 변경사항 추적
  • fatchmoviesmovieServiec.fetchMovies()호출 하여 서버로부터 데이터 받아오기

MovieListView

struct MovieListView: View {
    @StateObject private var viewModel = MovieListViewModel()
    @EnvironmentObject var pathModel: PathModel
    
    var body: some View {
        NavigationStack(path: $pathModel.paths) {
            Group {
                if viewModel.isLoading {
                    ProgressView()
                } else if let error = viewModel.errorMessage {
                    errorView(error)
                } else {
                    movieList
                }
            }
            .navigationTitle("영화 목록")
            .navigationDestination(for: PathType.self) { pathType in
                switch pathType {
                case .detail(let movieCd):
                    MovieDetailView(movieCd: movieCd)
                }
                
            }
            
        }struct MovieListView: View {
    @StateObject private var viewModel = MovieListViewModel()
    @EnvironmentObject var pathModel: PathModel
    
    var body: some View {
        NavigationStack(path: $pathModel.paths) {
            Group {
                if viewModel.isLoading {
                    ProgressView()
                } else if let error = viewModel.errorMessage {
                    errorView(error)
                } else {
                    movieList
                }
            }
            .navigationTitle("영화 목록")
            .navigationDestination(for: PathType.self) { pathType in
                switch pathType {
                case .detail(let movieCd):
                    MovieDetailView(movieCd: movieCd)
                }
                
            }
            
        }
       .....
  • PathModel로 화면 관리
MovieRow(movie: movie)
                .onTapGesture {
                    pathModel.paths.append(.detail(movieCd: movie.movieCd))
                }
  • onTapGesture로 리스트 클릭시 뷰 이동

@wotjs020708 wotjs020708 requested a review from y-eonee December 17, 2025 13:26
@wotjs020708 wotjs020708 self-assigned this Dec 17, 2025
Copy link
Collaborator

@y-eonee y-eonee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

잘보고갑니다...대박이네요

}
}

private func headerSection(_ movie: MovieInfo) -> some View {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

우와

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants