# FlittoTest [![Swift](https://camo.githubusercontent.com/b1f3b280edfd7000a65351ba99455663f436ca8361c7ff125e757162ed37939c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53776966742d352e352d6f72616e67652e737667)](https://camo.githubusercontent.com/b1f3b280edfd7000a65351ba99455663f436ca8361c7ff125e757162ed37939c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53776966742d352e352d6f72616e67652e737667) [![iOS](https://camo.githubusercontent.com/cf33e4ca0fa802e88ad36791c71d1abab38e579ea01f85b5565ca65f8df99912/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f506c6174666f726d2d694f532d6c69676874677265792e737667)](https://camo.githubusercontent.com/cf33e4ca0fa802e88ad36791c71d1abab38e579ea01f85b5565ca65f8df99912/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f506c6174666f726d2d694f532d6c69676874677265792e737667) ## 구동 화면 ![화면 기록 2022-01-29 오후 11 22 29](https://user-images.githubusercontent.com/62657991/151664553-19d28c96-2d2c-4802-9c3d-cbd46cce30d9.gif) ## 개발 환경 - iOS Deployment Target: 15.0 - Xcode Version: 13.2.1 - 외부 라이브러리 사용 X ## 키워드 - Combine(`ViewModel`, `Network` 등) - SwiftUI(`DetailView`) - MVVM-C(Clean Architecture) - CoreData - Toast - UnitTest ## 구현 내용에 대한 소회 ### SwiftUI TableView Cell을 클릭해서 push되는 `DetailView`를 SwiftUI로 작성했습니다. SwiftUI는 최근에 [AlertToast](https://github.com/elai950/AlertToast) 라이브러리를 참고하여 [개인 프로젝트](https://github.com/okstring/PlaygroundHub/tree/main/PlaygroundHub/Presentation/Common/SwiftUI)에 작성을 해봤는데 비교적 간단한 코드로 View를 구성하는 것이 매력적이고 잘 사용하면 더욱 유려한 Scene을 만들어 낼 수 있겠다 생각했습니다. 사전과제에서는 `@StateObject` , `@Published` 등을 이용해 ViewModel과 바인딩을 시켰고 ViewModel을 통한 변경사항에 대해 CoreData에 저장, `PassthroughSubject` 로 `ImageData`를 받아오도록 했습니다. 아무래도 UIKit과는 다른 패러다임의 코딩 방식이고 API가 비슷한 듯 다르기 때문에 러닝커브가 있었고(`GeometryReader`, `aspectRatio` 등) Binding 시 데이터의 흐름이 어떤 때에 어떻게 흐르는지 유의해서 작성해야 했습니다. ### Combine 부트캠프 과정 팀 프로젝트 당시 combine을 `@Published` 만 사용해보고 이번 사전과제에 기회가 되서 학습하며 사용해봤습니다. Combine 보다 RxSwift 가 비교적 익숙했던 저로써 비동기식 이벤트 처리의 컨셉을 되새기며 사용해봤습니다. 역시나 SwiftUI에서는 RxSwift 보다 Combine이 `@StateObject` , `@Published` 등을 통해 binding하는 것이 굉장히 자연스러웠습니다. SwiftUI를 사용할때는 Combine을 고려해봐야겠다라고 생각이 많이 들었던 이번 과제였습니다. 하지만 불편한 점도 있었는데 `.withLatestFrom` 와 같은 operator 종류에 대해 부족함을 느꼈고 Combine, RxSwift의 subject의 차이 등으로 어려움이 있는 등 RxSwift 와 비교해서 아쉬웠던 부분들이 많았습니다. 그럼에도 불구하고 SwiftUI와 Combine의 조합은 잘 어울렸고 UIKit, Combine, RxSwift, SwiftUI를 모두 사용한 프로젝트의 사례도 보면서 어떻게 조합해서 사용하는지 과제를 수행하면서 궁금했습니다. ### MVVM-C(Clean Architecture) 소프트웨어의 특징따라 개발자의 유지보수 비용을 줄이는 고민은 필수이기 때문에 아키텍처에 대해서도 고민은 당연하다고 생각했습니다. 그 중 MVVM이나 Clean Architecture에 관심을 가지고 작성을 해봤습니다. 비즈니스 로직을 분리하기 위해 ViewModel을 두고 테스트에도 용이하도록 하기 때문에 매력적이라 느꼈고 Network, Persistance, Usecase에 대해서도 분리를 해두어 역할에 용이하게끔 Clean Architecture 구조를 구성해봤습니다. 그리고 최대한 의존성 주입을 통해 SOLID 원칙 중 DIP를 지키기 위해 노력했습니다. 또한 Coordinator Pattern을 사용해 Scene을 transition 하는 부분을 나누어 최대한 구조적으로 만들도록 노력했습니다. 하지만 의문점이 드는 점은 이게 맞는 구조이고 효율적인 구조인가 하는 의문이 계속해서 들었습니다. 물론 소프트웨어 엔지니어는 항상 고민하는 직업이지만 잘못된 구조로 되려 손이 더 많이 가게 하지는 않는지 구조에 대한 고민은 항상 고민이 드는 것 같습니다. 이 원인은 오랫동안 운영되어 온 앱에 대해 꾸준히 운영을 해보지 못한 저의 갈증이 아닐까 생각이 듭니다. 또한 책 [클린 아키텍처](http://www.yes24.com/Product/Goods/77283734) 를 탐독하며 이후에 좀 더 심도있게 적용해보고 싶은 마음이 큽니다. 팀에 합류하게 된다면 플리토 앱을 통해 오랫동안 유지보수를 하고 노하우를 쌓고 고민과 배운 내용들을 다 같이 공유하며 선한 영향력을 끼치도록 노력하겠습니다.