Netflix Clone으로 알아보는 Code Base #02

Flamozzi·2023년 3월 21일
0
post-thumbnail

팔로잉 강의, 강의 선택 이유, 유의사항 등은 본 시리즈인 Netflix Clone으로 알아보는 Code Base #01을 참고해주시면 감사하겠습니다.

본 포스트에서 다루는 강의상 챕터

  • Creating Table's HeaderView
  • Customizing the navigation bar
  • Setting TableView sections titles
  • Sending URL Requests and Parsing JSON response
  • Using Extensions
  • Consuming API To Fetch Data for each Section
  • Refactoring Models
  • Creating Custom CollectionViewCell
  • Passing data to the CollectionView
  • Viewing poster images inside CollectionViewCell
  • Creating Upcoming TableView inside Upcoming Tab
  • Creating custom TableViewCell from the upcoming table
  • Creating TitleViewModel
  • Creating Top Search TableView inside TopSearch tab
  • Creating SearchResultsViewController to display search results
  • Querying database for inidividual movie
  • Using Youtube API
  • Parsing Youtube API Response
  • Handling sections of cells (Tapping on cells)
  • Creating TitlePreviewViewController
  • Refactoring TableViewHeader Hero title
  • Handling Tapping across all ViewControllers
  • Core Data (Best Practices)
  • Using Notification Center to update ViewControllers

그렇다.. 사실 Netflix Clone 개발 시리즈를 길게 가져가려고 했으나, #01 포스트를 작성한 이후로 본 강의를 빠르게 전부 수강해버렸다. 따라서 #01 이후의 모든 섹션을 진행하며 든 생각을 정리해보려고 한다.

본 포스트를 여러 포스트로 나눌까도 생각해보았지만, 당장 velog 포스팅 하는데에 많은 시간을 쏟기에 현재 담당하고 있는 테스크가 너무 많아서 빠르게 다음 스탭으로 넘어가고자 본 시리즈를 여기에서 마무리 하려고 한다.

당연히 #01 때와 마찬가지로 섹션을 진행하는데에 필요한 모든 지식을 여기서 정리하지 않는다. 포스트 작성자가 팔로잉 강의를 진행하며 든 생각과, 앱의 구조에 대해 분석해보는 것을 주된 목적으로 본 포스트를 작성함을 다시 한 번 밝힌다. 추후 별도의 포스트를 통해서 각 섹션에서 사용하는 다양한 iOS 프로그래밍에 관련한 지식을 정리하도록 하겠다.

진행 상황

vleog에서 사진을 첨부할 때 사진을 작은 크기로 여러장 옆으로 나열하는 것이 마음대로 컨트롤 안되는 것 같네요.. img tag를 사용하고 있는데도 뭔가 정렬이 제대로 안되는 느낌.. 이건 후에 방법을 찾아서 수정하도록 하겠습니다.

전체적으로 모든 구현을 완료하였다. 당연히 모든 영상에 대한 저작권은 없기 때문에, 유튜브의 트레일러 영상이 재생되도록 Youtube API를 사용하였다. 영화 포스터 이미지와 영화 정보들은 tmdb의 개발자 API를 사용하여 구현하였다.
CoreData를 사용하여 db내에 영화 정보를 다운 및 삭제할 수 있도록 구현하였다.

프로젝트 폴더 구조

📁Netflix Clone
	📁Managers
    	APICaller.swift
        	└ API 호출과 관련된 logic들을 담당
        DataPersistenceManager.swift
        	└ CoreData 관련 로직 담당 (download, fetching, delete)
    📁Resources
    	Extensions.swift
        	└ 각종 extension 담당 (ViewController에 대한 extension 제외)
        AppDelegate.swift
        SceneDelegate.swift
    📁Models
    	Title.swift
        	└ tmdb의 API를 통해 받아올 영화의 정보에 대한 model
        YoutubeSearchResponse.swift
        	└ 실제 보여지는 Youtube 영상의 id 등에 대한 model
    📁Views
    	CollectionViewTableViewCell.swift
        	└ tableView에 대한 각 cell에 대한 view
        HeroHeaderUIView.swift
        	└ Home tab에서 상단에 위치한 헤더 히어로 뷰
        TitleCollectionViewCell.swift
        	└ collectionview에 대한 각 cell에 대한 view
        TitleTableViewCell.swift
        	└ upcoming 혹은 search 등에서 보여지는 cell에 대한 view
    📁ViewModels
    	TitleViewModel.swift
        	└ 영상의 제목과 실제 포스터 데이터의 url을 가짐
        TitlePreviewViewModel.swift
        	└ 영상 포스터를 선택하면 로드되는 페이지에서 사용하는 ViewModel
              제목, 소개글, 실제 영상 데이터 등을 가짐
    📁Controllers
    	📁General
        	SearchResultsViewController.swift
            	└ search tap에서 타이틀을 검색했을 때 나타나는 뷰의 vc
            TitlePreviewViewController.swift
            	└ 영상 재생화면의 vc
    	📁Core
        	HomeViewController.swift
            	└ Home 탭의 vc
            UpcomingViewController.swift
            	└ Coming Soon 탭의 vc
            SearchViewController.swift
            	└ Top Searches 탭의 vc
            DownloadsViewController.swift
            	└ Downloads 탭의 vc
            MainTabBarViewController.swift
            	└ 각 탭을 담당하는 vc를 tabBar에 실제로 등록하는 전체 메인 골격 vc
    Assets.xcassets
    LaunchScreen.storyboard
    info.plist
    NetflixCloneModel.xcdatamodeld

본 프로젝트는 UIKit 프레임워크를 Code Base 기반으로 MVVM의 패턴을 채택하여 구성되어 있다. API 호출 혹은 CoreData 처럼 특수한 로직을 담당하는 경우 따로 그룹을 묶어서 클린한 구조를 유지하며, MVVM 패턴에 맞게 Model, View, ViewModel을 분리하고 있다. Extension 과 같이 추가로 구현해야하는 부분의 경우 따로 Resources 그룹으로 묶어 두었다.

프로젝트를 진행하며 느낀 소감

Netflix Clone을 만들어 보며 좋았던 점은 다음과 같다.

무엇보다도 UIKit 프레임워크를 사용한 앱을 Code Base로 개발해보는 경험을 할 수 있었다는 점이 개인적으로는 큰 의미로 다가왔다. 앱 개발을 처음 시작할 때는 접근 법에 대해서 굉장히 많이 고민하기 마련인데, 그런 시행착오를 줄일 수 있어서 좋았다. 특히, SwiftUI 프레임워크만을 사용하여 개발할 때는 ViewController에 대해서 명확하게 이해하지 못하였는데, 이제는 정보 검색을 할때나 vc에 대한 설명을 보아도 잘 이해할 수 있게 되었다. delegate 라던지, data source라던지.. 기존에는 이해할 수 없었던 UIKit 개발 근간에 대한 부분도 이제는 이해할 수 있게 되었다.

클론코딩에 대해서는 굉장히 부정적인 시각도 많은데, 그건 단순히 타이핑 만을 따라하며 강의를 따라갈 경우 발생하는 문제들에 대한 시각이라고 생각한다. 기존에 존재하는 프로덕트의 기능 및 디자인을 따라가며 실제로 구현해보는 것은 해당 앱의 생태 및 다른 앱들이 어떤 식으로 개발되어 가는지 전체적인 맥락을 이해하는데에 큰 도움이 되었다.

그 동안은 Alamofire를 이용하여 API 통신을 처리하였는데, 이번에는 Swift 퓨어 코드를 사용하여 API 호출을 처리하였다. 또한 APICaller manager와 같이 특수한 기능을 그룹으로 묶어 로직을 분리하여 클리한 구조를 도모하는 것이 좋았다.

하지만, 아쉬웠던 점 또한 분명히 존재한다.

MVVM 패턴을 채택하였다고는 하나 사실상 ViewController의 역할이 계속해서 무거워지고, ViewModel에 대한 명확한 역할을 부여하지 못한 것 같다. (이건 사실상 MVC 패턴이 아닌지..)

iOS 앱을 처음 개발할 당시에 SwiftUI + MVVM 구조를 선택한 것 역시 파일별 의존도의 명확함 및 로직 분리를 위한 것이었는데, 본 프로젝트를 진행하며 더욱 로직 분리에 대한 확신이 강해졌다 😅

물론 본 강의에서도 충분히 깔끔한 구조를 위해 그룹핑을 하는 등 구조 자체에 대해서는 만족한다. 내 UIKit 숙련도가 부족했을 뿐. 이번 클론 프로젝트를 기반으로 다른 프로덕트를 만들 때는 꼭 더 완성도 있게 만들어 봐야겠다.

ViewController에서 View에 대한 부분을 완전히 분리하지 못하다보니 VC가 계쏙해서 비대해지고, 사실상 ViewModel과 Model의 역할이 명확하게 구분되지 못하였다는 것이 원인이라고 생각한다.

현업에서 종사하시는 선배 개발자님들의 말을 빌리자면 어설프게 아키텍처를 적용해서 가져온 코드보다 MVC에 충실한 코드가 인계 받을 때 훨씬 알아보기 좋다고도 한다. 즉, 패턴에 정답은 없으며, 그 만큼 명확하게 설계를 하기 어렵다는 말이기도 하다. 하지만 그만큼 명확하게 했을 때는 더 큰 이득을 가져오지 않겠는가? 더 열심히 고민하고 구현하며 노력해야겠다.

또 한가지 아쉬웠던 점은 SwiftUI 프로젝트에 비해서 확실히 가독성이 많이 떨어진다. 나름대로 깔끔한 구조를 가져가고자 노력했음에도 한 눈에 코드가 잘 들어오지 않는다. 물론 나의 숙련도에 기인한 아쉬움이겠지만, 이를 Apple도 의식하여 만든 것이 SwiftUI이지 않겠는가. (많은 이유가 있겠지만, 분명 가독성도 한몫했을 것이라 생각함)

앞으로의 방향성

Netflix Clone 개발을 마무리하며 앞으로의 방향성을 다시 검토해보자면 다음과 같다.

삽질이 많이 필요한 부분이지만 MVVM, MVC, TCA 등 다양한 아키텍처에 대해 좀 더 명확한 개념 확립이 필요할 것 같다. 당연히 한 번에 완벽한 구조를 만들 수는 없고, 계속 만들고 수정해보며 필요 및 의도를 명확하게 이해할 필요가 있어 보인다.

현업에서도 그렇고 현재 100% SwiftUI 만을 이용해서 프로젝트를 하는 경우는 잘 없다. (신규 프로젝트의 경우에는 적극 사용하긴 하는 듯) 따라서 SwiftUI + MVVM(혹은 필요에 따라 TCA와 같은 다른 패턴) 구조를 채택하여 앱을 개발하면서 중간중간 필요한 부분에 UIKit을 가져와서 구현하는 것도 현명한 방법이라는 생각이 들었다.

만약 UIKit 만을 이용하여 프로젝트를 추가로 진행한다면, MVVM 패턴이 잘 지켜질 수 있도록 vc에서 사용할 View들을 잘 쪼개서 따로 구현해주고, vc에서는 조립하는 느낌으로 깔끔하게 구현하면, 로직에 대한 부분도 자연스럽게 vc가 아닌 ViewModel 로 잘 이전 될 것이라고 생각한다.

다음으로는 트위터 같은 커뮤니티 서비스를 SwiftUI로 구현해보며 좀 더 명확한 시각을 가지기 위해 노력해보아야겠다.

References

profile
개발도 하고, 글도 적고

0개의 댓글