[TIL] 봐도봐도 어려운 MVVM & RxSwift

Eden·2025년 1월 11일
1

TIL

목록 보기
94/129
post-thumbnail

1. MVVM 패턴

MVVM(Model-View-ViewModel)은 iOS 앱 개발에서 자주 사용하는 아키텍처 패턴 중 하나다. 각각의 역할을 명확히 나누어 코드 재사용성과 유지보수를 높이는 것이 목적이다 !

구성 요소

  1. Model

    • 데이터와 비즈니스 로직을 담당.
    • API에서 가져온 데이터, 데이터베이스의 정보 등을 포함.
  2. View

    • 사용자 인터페이스(UI)를 담당.
    • UIViewController, 화면에 표시되는 버튼, 라벨 등이 여기에 해당.
  3. ViewModel

    • View와 Model 사이에서 다리 역할.
    • Model의 데이터를 가공하여 View에 전달.
    • View의 액션(사용자 입력 등)을 받아서 Model에 반영.

MVVM 데이터 흐름

  • View는 ViewModel을 구독(바인딩)하고, ViewModel은 Model을 사용.
  • Model에서 데이터가 변경되면 ViewModel을 통해 View에 전달.
  • View의 액션(버튼 클릭 등)은 ViewModel로 전달되어 Model에 반영.

MVVM의 장점

  • 역할 분리가 명확해서 유지보수와 테스트가 쉬움.
  • ViewModel에 비즈니스 로직을 넣어 View의 의존성을 줄임.

2. RxSwift란?

RxSwift는 비동기 데이터 흐름이벤트 처리를 간단하게 할 수 있게 도와주는 라이브러리. Reactive Programming(리액티브 프로그래밍)을 iOS에 적용할 때 사용된다.

주요 개념

  1. Observable (관찰 가능한 객체)

    • 데이터를 지속적으로 전달하는 스트림(흐름)
    • 데이터를 방출(emit)하거나, 이벤트를 방출
  2. Observer (관찰자)

    • Observable을 구독(subscribe)해서 방출된 데이터를 받음
  3. Binding

    • RxSwift를 활용하면 View와 ViewModel 간 데이터를 쉽게 바인딩할 수 있음

RxSwift 주요 연산자

  • map: 데이터를 변환
    observable.map { $0 * 2 }
  • filter: 특정 조건에 맞는 데이터만 통과
    observable.filter { $0 > 10 }
  • combineLatest: 여러 Observable을 합침
    Observable.combineLatest(observable1, observable2)

3. MVVM + RxSwift 예제

1) Model

struct User {
    var name: String
}

2) ViewModel

import RxSwift
import RxCocoa

class UserViewModel {
    // 텍스트 필드 입력 값을 Observable로 노출
    let name = BehaviorRelay<String>(value: "")
}

3) View (ViewController)

import UIKit
import RxSwift
import RxCocoa

class ViewController: UIViewController {
    private let textField = UITextField()
    private let label = UILabel()
    private let disposeBag = DisposeBag()
    private let viewModel = UserViewModel()

    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        setupBindings()
    }

    private func setupUI() {
        view.backgroundColor = .white

        textField.borderStyle = .roundedRect
        textField.placeholder = "Enter name"

        label.textAlignment = .center
        label.textColor = .black

        let stackView = UIStackView(arrangedSubviews: [textField, label])
        stackView.axis = .vertical
        stackView.spacing = 16
        stackView.translatesAutoresizingMaskIntoConstraints = false

        view.addSubview(stackView)

        NSLayoutConstraint.activate([
            stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
            stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16)
        ])
    }

    private func setupBindings() {
        // View -> ViewModel 바인딩
        textField.rx.text.orEmpty
            .bind(to: viewModel.name)
            .disposed(by: disposeBag)

        // ViewModel -> View 바인딩
        viewModel.name
            .bind(to: label.rx.text)
            .disposed(by: disposeBag)
    }
}

4. 핵심 요약

  • MVVM은 역할을 나눠 유지보수를 쉽게 하고, ViewModel을 통해 데이터 가공과 로직 처리를 담당.
  • RxSwift는 MVVM에서 데이터 바인딩을 효율적으로 할 수 있게 도와줌.
  • Observable과 Binding을 통해 데이터 흐름을 선언적으로 처리할 수 있음.
profile
Frontend🌐 and iOS

3개의 댓글

comment-user-thumbnail
2025년 1월 11일

오.. 저 이번에 .map 썼어요
버튼 탭 이벤트 추적할 때 .rx.tap 썼는데 얘는 기본적으로 Observable를 방출한다고 해요.
그래서 필요한 값을 방출하도록 바꿔줄때 .map을 써야 되더라구욤

1개의 답글

관련 채용 정보