Clean Swift (a.k.a VIP) 에 대해 아라보자

Yang Si Yeon·2021년 1월 20일
5

개요

Clean Swift는 Uncle Bob이 제시한 Clean Architecture를 iOS 앱 개발에 적용시킨 것이다. Clean Swift 아키텍처를 좀 더 편하게 적용하기 위해서는 먼저 Clean Swift 템플릿을 다운 받아야 한다.

Clean Swift 템플릿 다운로드

MVC 패턴으로 구성된 프로젝트에서는 코드들이 Models, Views, Controllers로 묶여있다. 그에 비해 Clean Swift에서는 구조가 Scenes 을 중심으로 짜여진다. 그리고 Clean Swift를 이루는 컴포넌트들은 다음과 같다.

  • View Controller
  • Interactor
  • Presenter
  • Router
  • Worker
  • Models
  • Configuration

위 컴포넌트들은 UseCase를 기반으로 제작되며, 각 컴포넌트는 데이터 송수신을 위한 protocol을 가지고 있다.

위에서 소개한 Xcode 템플릿을 사용하면 쉽게 컴포넌트들을 생성할 수 있다.

컴포넌트 사이의 통신은 위 다이어그램처럼 이루어진다. 꼭 기억해두자!

VIP

제목에서 알 수 있듯이 Clean Swift에서 가장 중요한 컴포넌트들은 View Controller, Interactor, Presenter 3가지이다. 각 컴포넌트들은 아래 다이어그램과 같이 서로에게 input이 되고, output이 된다.

View Controller

Clean Swift의 flow diagram에서 볼 수 있듯이 View Controller는 Interactor와 통신하고 Presenter로 부터 응답을 받는다. 또한 전환이 필요한 경우 라우터와 통신한다.

View Controller의 역할은 다음과 같다.

  • data를 화면에 뿌려주기
  • 사용자와 인터렉션

View Controller에서는 Display Logic 프로토콜 1개를 가지고 있다. 해당 프로토콜에서는 화면에 데이터를 바인딩 시켜주는 일을 한다.

Interactor

Interactor는 Worker와 Presenter 사이의 중재자이다.

Interactor의 역할은 다음과 같다.

  • View Controller와 통신해서 Worker에 필요한 request data 받아오기
  • Worker에서 일을 진행하기 전에 모든 값이 제대로 전송되었는지 확인하기 위해 유효성 검사
  • Worker로부터 reponse를 받으면 얘를 Presenter에게 전송

Interactor는 2가지 타입의 포로토콜을 가지고 있다. (Router와 비슷)

  1. Business Logic Protocol
    Interactor의 모든 함수는 이 프로토콜에 선언되고, View Controller에서 Interactor의 모든 함수들을 이용할 수 있다.
  1. Data Store Protocol
    현재 상태를 유지해야하는 모든 프로퍼티들은 이 프로토콜에 선언되어야 한다. 이 프로토콜은 주로 Router와 View Controller 사이에 통신하는 데 사용된다.

Presenter

Presenter는 presentatoin 로직을 담당한다.

Presenter의 역할은 다음과 같다.

  • Interactor에서 얻은 response를 ViewModel로 포맷하고, 이를 View Controller로 전달
  • 데이터가 사용자에게 표시되는 방법을 결정

Presenter는 Presentation Logic 프로토콜 1개를 가지고 있다. 해당 프로토콜에서는 View Controller에서 선언된 delegate 메서드를 호출하며, 이를 통해 ViewModel를 전송한다.

VIP 주기

새 기능을 구현할 때는 다음과 같은 순서로 개발을 진행하는 것이 좋다.

  1. IBAction 메소드나 viewDidLoad()로부터 Use Case를 트리거 한다.
  2. View Controller는 Interactor를 호출하고, Interactor는 비즈니스 로직을 수행한다.
  3. Interactor는 Presenter를 호출하고, 결과를 Primitive Types로 형식화 시킨다.
  4. Presenter는 View Controller를 호출하고, View Controller는 결과를 화면에 보여준다.

VIP 외의 것들

위에서는 View Controller, Interactor, Presenter 밖에 안쓰는 것 처럼 말했지만, 사실 다른 애들도 있다. 예를 들어 위 VIP 주기에서 Interactor 에서 처리하기엔 복잡한 비즈니스 로직이나 서버와의 통신을 진행하는 일, 또는 데이터를 저장하는 그릇, 화면을 전환하는 일 등과 같이 다양한 일을 하는 친구들에 대해 알아보자.

Models

Models에서 컨트롤러와 관련된 모든 모델을 저장한다. Models 클래스는 각각 컴포넌트와 관련있고, 구조체 유형이며 request, response, viewModel 구조체를 포함한다.

import UIKit

struct TestModel {
    struct Fetch {
        struct Request
        {
            var itemId = 0
            var keyword: String?
            var count: String?
        }
        struct Response
        {
            var testObj: Test?
            var isError: Bool
            var message: String?
        }
        struct ViewModel 
        {
            var name: String?
            var date: String?
            var desc: String?
            var isError: Bool
            var message: String?
        }
     }
 }

위 코드는 API 호출 작업과 관련된 일을 하는 코드이다. 이때 다음과 같은 구조체가 필요하다.

  • Request: API request로 보낼 파라미터들
  • Response: API의 response를 저장
  • ViewModel: UI를 보여주는데 필요한 모든 데이터들

👉 주의해야 할 점
Clean Swift의 예시로 많이 활용되는 CleanStore 프로젝트를 참고하면,
CleanStore/Models 그룹이 있고, CleanStore/Scenes/CreateOrder/CreateOrderModels 가 있다. 위에서 설명하는 Models는 후자이다.

CleanStore/Models 안에 있는 구조체는 클린 아키텍처에서 말하는 엔티티처럼 프로그램의 기본이 되는 가장 일반적인 도메인이다. 아래와 같은 형태를 갖는다.

import Foundation

struct Order: Equatable
{
  // MARK: Contact info
  var firstName: String
  var lastName: String
  var phone: String
  var email: String
  
  // MARK: Payment info
  var billingAddress: Address
  var paymentMethod: PaymentMethod
  
  // MARK: Shipping info
  var shipmentAddress: Address
  var shipmentMethod: ShipmentMethod
  
  // MARK: Misc
  var id: String?
  var date: Date
  var total: NSDecimalNumber
}

CleanStore/Scenes/CreateOrder/CreateOrderModels 안에 있는 구조체들은 View Controller, Interactor, Presenter에서 필요로 하는 데이터들의 형태를 따라 만들어진 구조체들이다.

따라서 UseCase, 즉 해당 scene(화면)에서 사용자에게 제공하는 기능별로 request, response, viewModel이라는 그릇을 만들고 여기에 데이터를 담아 서로 주고 받는 용도로 사용된다.

  • request: View Controller -> Interactor
  • response: Interactor -> Presenter
  • viewModel: Presenter -> View Controller

Router

Router는 View Controller 간의 전환과 데이터 전달을 처리한다.

Router는 2가지 타입의 포로토콜을 가지고 있다. (Interactor와 비슷)

  1. Routing Logic Protocol
    라우팅에 사용되는 모든 함수는 해당 프로토콜에 선언되어 있다.
  1. Data Passing Protocol
    목표 View Controller로 전달해야하는 data를 가지고 있는 프로토콜이다.

Worker

Worker는 API/CoreData request와 response를 관리하며, Interactor와 통신한다. Interactor에게서 data를 받아 request를 날리고, response로 받은 data를 Interactor에게 넘겨준다.

참고

https://hackernoon.com/introducing-clean-swift-architecture-vip-770a639ad7bf

https://github.com/Clean-Swift/CleanStore

https://eunjin3786.tistory.com/165

profile
가장 젊은 지금, 내가 성장하는 데에 쓰자

1개의 댓글

comment-user-thumbnail
2021년 1월 20일

실제 사용해본 소감과 MVC, MVVM과 비교해서 어떤 장단점이 있는지도 궁금하네요~

답글 달기