Можно ли использовать архитектуру VIPER со SwiftUI?

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

Ответ

Да, можно адаптировать, но это требует переосмысления некоторых компонентов, так как SwiftUI основан на декларативном и реактивном подходе.

Адаптация компонентов VIPER для SwiftUI:

Компонент Роль в SwiftUI Реализация
View Декларативное описание UI. SwiftUI View. Получает данные от Presenter через @ObservedObject или @StateObject.
Presenter Преобразует данные от Interactor для View, обрабатывает действия пользователя. Класс, наследующий ObservableObject. Содержит @Published свойства.
Interactor Содержит бизнес-логику, работу с сетью и данными. Обычный класс, как в UIKit.
Entity Модели данных. Без изменений (структуры).
Router Управление навигацией и сборкой модулей. Адаптируется под NavigationStack, модификаторы .sheet и т.д. Часто реализуется как координатор.

Пример связи View и Presenter:

// VIEW
struct ArticleListView: View {
    @StateObject var presenter: ArticleListPresenter // Presenter как StateObject

    var body: some View {
        List(presenter.articles) { article in
            Text(article.title)
                .onTapGesture { presenter.didSelect(article) }
        }
        .onAppear { presenter.viewDidAppear() }
    }
}

// PRESENTER
class ArticleListPresenter: ObservableObject {
    @Published var articles: [Article] = []
    let interactor: ArticleListInteractorProtocol
    let router: ArticleListRouterProtocol

    func viewDidAppear() {
        articles = interactor.fetchArticles()
    }

    func didSelect(_ article: Article) {
        router.showDetails(for: article)
    }
}

Вывод: VIPER в SwiftUI возможен, но часто считается избыточным. Более естественными являются паттерны MVVM или Model-View.