Swift UI + MVVM 과연 맞을까?

김재형·2024년 5월 15일
0
post-custom-banner

Swift UI 과연 MVVM 으로 해야할까?

최근에 Swift UI를 입문하게 되면서 정들었던 😍UIKit과 🥺RxSwift 를 떠나
Combine을 학습하면서 고민하게된 사연입니다.

UIKit은 위와같은 MVC 구조로 되어있어서
UIViewControlelr의 역활을 줄여주기 위해

위와같은 MVVM 패턴을 도입하여 비즈니스 로직View 를 분리 하였었습니다.

그럼 스유는 무엇을 기반으로 하고있을까요?
WWDC 2019 KeyNote (2:07:40 초 부터 보시면 좋아요) 를 한번 봐보죠

https://youtu.be/psL_5RIBqnY

보고 오셨나용?
해당 영상에선 슬프게도 UIKit의 단점(뷰 코드가 길어)를 보완하여 반응형으로 해줄께 라고 하고있습니다.
자. 반응형입니다.

  • Swift UI는 @State, @Binding 이 존재합니다.
  • 선언형 구문 (declarative syntaz)
  • 데이터 중심 (data driven)

위 말처럼 SwiftUI는 값이 변경됨을 감지하게 해주는 @State@Binding 이 존재합니다.
즉 정말 특별한 비즈니스 로직 이 필요 없는이상 더이상 뷰모델을 필요가 없어진거죠.

Model 이 업데이트 될 때 View에다가 반영하기 위해선 View를 참조해야 하는데,
아쉽게도 SwiftUI의 View는 Struct 이기 때문에 참조할 수 없습니다.
그래서 컨테이너 라는 개념이 존재하는데 다음 시간에 다루도록 하겠습니다.

자 한번 생각 해볼께요 구조체 기반인 SwiftUI의 뷰 변화를 주기위해 @State 또는 @Binding
을 사용 해본다고 해보겠습니다.
자 뷰모델에 반응 시켜야 하는 상황이라면 그때또 Binding 혹은 PassthroughSubject<> 등을 이용해서
또 반응해주어야 합니다.

이상하지 않나요? 이미 반응해주고 있는데 또 반응하는것을 두어 사용해야 하는 점이요
반응 하더라도 양방향인 MVVM ...? 과연 옳을까요,
반응 하더라도 뷰보델이 더 가벼워 질순 없는 걸까요?
Swift UI는 단항향 플로우 기반인데 양방향 플로우로 만드는게 맞을까요?
그래서 새로운 패턴인 MVI 대해서 알아 보도록 해보겠습니다.

MVI 의 등장

MVVM과 비슷한 아키텍쳐 패턴으로 단방향 데이터 흐름을 가진 패턴입니다.
View -> 사람이 액션~ -> intent -> 뷰모델에서 처리 -> 상태 변경 -> View 상태 반영

Model

앱 상태를 나타내며, 상태 관리의 중심입니다.

struct AppState {
    var count: Int = 0
}

Intent

사용자 인터랙션 혹은 뷰(외부)의 이벤트를 모델로 전달하는 역할을 합니다.

enum AppIntent {
    case increment
    case decrement
}

ViewModel

Intent 의 이벤트를 처리하고 상태를 업데이트 합니다

class AppViewModel: ObservableObject {
    @Published private(set) var state = AppState()
    
    func send(_ intent: AppIntent) {
        switch intent {
        case .increment:
            state.count += 1
        case .decrement:
            state.count -= 1
        }
    }
}

View

뷰에 반영시 예시 코드 입니다.


struct ContentView: View {

    @StateObject 
    private var viewModel = AppViewModel()
    
    var body: some View {
        VStack {
            Text("Count: \(viewModel.state.count)")
                .font(.largeTitle)
            
            HStack {
                Button(action: {
                    viewModel.send(.decrement)
                }) {
                    Text("-")
                        .font(.largeTitle)
                        .padding()
                }
                
                Button(action: {
                    viewModel.send(.increment)
                }) {
                    Text("+")
                        .font(.largeTitle)
                        .padding()
                }
            }
        }
    }
}

MVVM 과 차이가 뭔데요?

MVVM 은 input output 패턴으로 만들었다고 하여도
양방향 플로우가 불가능 한것이 아니며, 인풋을 구성할때도 따로 바인딩 할수있게 했어야 했기에
MVI 패턴인 단방향 플로우와의 차이점은 분명하다고 생각합니다.

장점은요?

데이터의 흐름이 단 향이라 정흐름을 이해하고 유지보수에 도움이 됩니다.
다만 변경되는 모든것들이 intent를 통해야 함으로 아무리 간단한 뷰라도
최소한 intentmodel이 필요합니다.

참고하면 좋은 사이트

https://betterprogramming.pub/mvi-architecture-for-swiftui-apps-cff44428394

profile
IOS 개발자 새싹이
post-custom-banner

0개의 댓글