Как реализовать архитектуру MVVM в UIKit?

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

Ответ

MVVM (Model-View-ViewModel) в UIKit разделяет ответственность:

  • Model — данные и бизнес-логика.
  • ViewUIViewController и UIView, отвечающие за отображение.
  • ViewModel — преобразует Model в данные, готовые для отображения View, и содержит презентационную логику.

Базовая реализация:

// MARK: - Model
struct User {
    let name: String
    let age: Int
}

// MARK: - ViewModel
class UserViewModel {
    private let user: User

    // Преобразование данных для View
    var displayName: String { "User: (user.name)" }
    var displayAge: String { "Age: (user.age)" }

    init(user: User) {
        self.user = user
    }
}

// MARK: - View (ViewController)
class UserViewController: UIViewController {
    @IBOutlet private weak var nameLabel: UILabel!
    @IBOutlet private weak var ageLabel: UILabel!

    var viewModel: UserViewModel! {
        didSet { updateView() }
    }

    private func updateView() {
        nameLabel.text = viewModel.displayName
        ageLabel.text = viewModel.displayAge
    }
}

Ключевые принципы:

  1. ViewModel не имеет ссылок на UIKit. Она независима от слоя представления.
  2. View (ViewController) становится "глупым". Он только отображает данные из ViewModel и передаёт ей пользовательские действия.
  3. Связывание (Binding): Для реактивного обновления View при изменении ViewModel используйте:
    • Closures или делегаты для простых случаев.
    • Combine фреймворк (iOS 13+) для декларативного биндинга.
    • RxSwift или ReactiveCocoa в сторонних проектах.

Преимущества: Упрощается тестирование (ViewModel тестируется без UIKit), уменьшается связанность кода, ViewController становится менее массивным.