MVVM의 기본규칙

  • View는 ViewModel을 가지고, ViewModel은 Model을 가짐
  • ViewModel은 입출력을 처리하고 UI가 요구하는 로직을 처리하는 역할만을 수행
  • ViewModel은 UI를 수정할 수 x

DataBinding이란?

  • 단순히 앱의 UI와 UI가 표시하는 데이터 사이의 연결을 설정하는 프로세스
  • MVVM 뿐만 아니라 다른 디자이 패턴에도 적용 가능
  • 데이터를 ‘제공’하는 자와 그 데이터를 ‘사용’하는 자를 연결시켜 동기

DataBinding의 방법

Observables

  1. Obserbavles 정의
    class Observable<T> {
     private var listener: ((T?) -> Void)?
    
     var value: T? {
         didSet {
             self.listener?(value)
         }
     }
        
     init(_ value: T?) {
         self.value = value
     }
        
     func bind(_ listener: @escaping (T?) -> Void) {
         listener(value)
         self.listner = listener
     }
    }
    
  2. ViewModel 정의
    class ClockViewModel {
        
     var observableWeather: Observable<String> = Observable("맑음")
        
     func setWeather() {
         NetworkService.networkService.getWeather() { weather in
             observableWeather.value = weather
         }
     }
    }
    
  3. ViewController에서 동작을 구현
     viewModel.observableWeather.bind { _ in
         self.collcetionView.reload()
    }
    

Combine

  1. ViewModel 정의
    class ClockViewModel {
     @Published var combineWeather: String = "맑음"
    
     func setWeather() {
          NetworkService.networkService.getWeather() { weather in
             observableWeather.value = weather
         }
     }
    }
    
  2. ViewController에서 동작을 구현
     private var cancellables: Set<AnyCancellable> = []
    
     viewModel.$combineTime
                 .compactMap { String($0) }
                 .assign(to: \.text, on: conbineWeatherLabel)
                 .store(in: &cancellables)
    

EventBus / NotificationCenter

  1. 모든 subscriber에게 EventBus로 보낼 이벤트 생성
    class WeatherEvent: NSObject {
     var error: Bool
     var errorMessage: String?
     var weather: [weather]?
        
     init(error: Bool, errorMessage: String? = nil, weather: [weather]? = nil) {
         self.error = error
         self.errorMessage = errorMessage
         self.weather = weather
     }
    }
    
  2. EventBus를 이용해서 ViewModel로 부터 이벤트 발생
    func callEvent() {
     EventBus.post(
         "fetchWeather",
         sender: WeatherEvent(error: error, errorMessage: errorMessage, weather: weather)
     )
    }
    
  3. ViewController에서 이벤트 구독
    func setupEventBusSubscriber() {
     _ = EventBus.onMainThread(self, name: "fetchWeather") { result in
         if let event = result!.object as? WeatherEvent {
             if event.weather != nil {
                 self.collcetionView.reload()
             } else if let message = event.errorMessage {
                 self.showAlert(title: "Error", message: message)
             }
         }
     }
    }
    

FRP Technique (RxCocoa / RxSwift)

  • Functional / Reactive Programming

댓글남기기