Какой у вас опыт с реактивным программированием в архитектуре MVVM?

«Какой у вас опыт с реактивным программированием в архитектуре MVVM?» — вопрос из категории Реактивное программирование, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Имею опыт реализации паттерна MVVM с реактивными фреймворками: Combine в связке со SwiftUI и RxSwift для UIKit.

Пример с Combine + SwiftUI:

class ItemsViewModel: ObservableObject {
    @Published var items: [Item] = []
    @Published var isLoading = false
    private var cancellables = Set<AnyCancellable>()

    func loadData() {
        isLoading = true
        NetworkService.fetchItems() // Возвращает AnyPublisher<[Item], Error>
            .receive(on: DispatchQueue.main)
            .sink(
                receiveCompletion: { [weak self] completion in
                    self?.isLoading = false
                    if case .failure(let error) = completion {
                        // Обработать ошибку
                    }
                },
                receiveValue: { [weak self] fetchedItems in
                    self?.items = fetchedItems
                }
            )
            .store(in: &cancellables)
    }
}

// Во View:
struct ItemsView: View {
    @StateObject var viewModel = ItemsViewModel()
    var body: some View {
        List(viewModel.items) { item in
            Text(item.name)
        }
        .onAppear { viewModel.loadData() }
    }
}

Преимущества подхода:

  • Декларативный биндинг: View автоматически реагирует на изменения @Published свойств.
  • Управление состоянием: Легко обрабатывать загрузку, данные и ошибки.
  • Тестируемость: ViewModel можно тестировать изолированно, подменяя источники данных.
  • Отмена операций: AnyCancellable автоматически управляет жизненным циклом подписок.