Що таке MVC в iOS-розробці та чим відрізняється від MVP і MVVM?
Архітектурний патерн визначає, як організований код застосунку: хто відповідає за дані, хто – за відображення, хто – за логіку. Вибір патерну впливає на тестованість, швидкість розробки і те, наскільки легко підтримувати проєкт через рік. Патерни проєктування MVC, MVP і MVVM – три найпоширеніших підходи в iOS, і у кожного є своя сфера застосування.
Що таке патерн MVC і навіщо він потрібен?
MVC патерн (Model-View-Controller) – це архітектурний шаблон, який ділить застосунок на три компоненти з чіткими зонами відповідальності. Згідно з офіційною документацією Apple, MVC є базовим патерном Cocoa і рекомендований як відправна точка для будь-якого iOS-застосунку.
Model – зберігає дані та бізнес-логіку. Не знає нічого про View і Controller. Приклад: структура User, клас UserService, робота з CoreData або мережею.
View – відповідає за відображення. UILabel, UIButton, UITableView. Не містить логіки – лише рендеринг даних, які їй передали.
Controller – медіатор між Model і View. Отримує дані з Model, форматує їх і передає у View. Обробляє дії користувача та ініціює зміни в Model.
MVC простими словами: Controller – це менеджер. View – вітрина магазину. Model – склад. Покупець (користувач) бачить лише вітрину, менеджер вирішує, що на ній показати і як обробити замовлення.
Як влаштований MVC в iOS: Model, View, Controller
MVC iOS – це не зовсім класичний Gang of Four MVC. Apple модифікувала патерн для UIKit: у класичній версії View і Model можуть спілкуватися безпосередньо, в Apple MVC – ні. View взаємодіє лише з Controller через target-action і delegation, Controller звертається до Model і оновлює View.
Практично це означає: UIViewController в iOS завжди є Controller. Він володіє View (через IBOutlet або programmatic layout) і реагує на події View (через IBAction або делегування). Саме тому на UIViewController лягає величезне навантаження.
Приклад типової зв'язки в UIKit:
// Модель
struct Article { let title: String; let body: String }
// View – UITableViewCell (налаштовується ззовні)
// Controller
class ArticleListVC: UIViewController, UITableViewDataSource {
var articles: [Article] = []
func viewDidLoad() {
super.viewDidLoad()
loadArticles() // звернення до Model
}
func tableView(_ tv: UITableView, cellForRowAt ip: IndexPath) -> UITableViewCell {
let cell = tv.dequeueReusableCell(withIdentifier: "Cell", for: ip)
cell.textLabel?.text = articles[ip.row].title // оновлення View
return cell
}
}
Вибір технологічного стеку для iOS – окрема тема: Swift vs Objective-C, UIKit vs SwiftUI, нативна розробка vs кросплатформа. Огляд підходів – у матеріалі «Оптимальні технології та мови для розробки застосунків на iOS».
Чому MVC призводить до Massive ViewController?
Проблема Massive View Controller – прямий наслідок Apple MVC. Оскільки Controller – єдиний медіатор між View і Model, до нього поступово потрапляє все: мережеві запити, форматування даних, навігаційна логіка, обробка помилок, аналітика. За спостереженнями команди Netguru, UIViewController у реальних MVC-проєктах нерідко виростає до 1 000-2 000 рядків коду.
Типовий вміст «роздутого» ViewController у MVC-проєкті: завантаження даних із мережі (виклик API, парсинг відповіді), форматування дат, рядків, валют для відображення, обробка станів (loading / success / error), навігація між екранами, аналітика та логування подій, керування UITableView або UICollectionView через delegate і dataSource.
Головний наслідок – низька тестованість. Юніт-тест для Controller майже неможливий без запуску UIKit: не можна перевірити бізнес-логіку в ізоляції, якщо вона перемішана з кодом оновлення UI.
MVC vs MVP: у чому різниця?
MVC vs MVP – це передусім різниця в тому, хто знає про UIKit. У MVC Controller безпосередньо працює з UIView, UIButton, UILabel. У MVP вводиться Presenter – об'єкт, який містить всю логіку екрана, але нічого не знає про UIKit. View (UIViewController) реалізує протокол і просто виконує команди Presenter.
Приклад: у MVC метод loginTapped() у ViewController сам валідує поля, викликає API та оновлює UI. У MVP – ViewController викликає presenter.loginTapped(email:, password:), а Presenter виконує логіку і викликає view.showError() або view.navigateToHome() через протокол.
// MVP: протокол View
protocol LoginView: AnyObject {
func showError(_ message: String)
func navigateToHome()
}
// Presenter – не імпортує UIKit
class LoginPresenter {
weak var view: LoginView?
func loginTapped(email: String, password: String) {
guard !email.isEmpty else { view?.showError("Email порожній"); return }
// логіка автентифікації
view?.navigateToHome()
}
}
Ключовий виграш MVP: Presenter тестується як звичайний Swift-клас без емулятора. Достатньо передати мок-об'єкт View через протокол і викликати метод – вся поведінка перевіряється в unit-тесті.
У чому відмінність MVC від MVVM?
Різниця MVC і MVVM – у механізмі зв'язку між View і даними. У MVC Controller вручну оновлює View: отримав дані → написав label.text = value. У MVVM ViewModel публікує дані через Combine (або RxSwift), а View підписується на зміни та оновлюється автоматично без явних викликів з боку ViewModel.
Приклад біндингу через Combine у MVVM:
class ArticleViewModel: ObservableObject {
@Published var title: String = ""
private var article: Article
init(article: Article) {
self.article = article
self.title = article.title
}
}
// View (ViewController)
viewModel.$title
.receive(on: RunLoop.main)
.assign(to: \.text, on: titleLabel)
.store(in: &cancellables)
MVC vs MVVM: ViewController у MVVM стає «тонким» – він лише підписується на публікації ViewModel і передає дії користувача. ViewModel не знає про існування View, що робить її повністю тестованою. Окрема перевага: MVVM нативно сумісний із SwiftUI через @ObservedObject і @StateObject.
Коли використовувати MVC, а коли переходити на MVP або MVVM?
| Критерій | MVC | MVP | MVVM |
|---|---|---|---|
| Складність входу | 🟢 Низька | 🟡 Середня | 🔴 Вище середнього |
| Тестованість | 🔴 Низька | 🟢 Висока | 🟢 Висока |
| Обсяг коду | 🟢 Мінімальний | 🟡 Середній | 🟡 Середній |
| Масштаб проєкту | 🟢 Малий / Прототип | 🟡 Середній | 🟢 Середній / Великий |
| Популярність в iOS (UIKit) | 🟢 Дуже висока | 🟡 Середня | 🟢 Висока |
| Сумісність із SwiftUI | 🟡 Обмежена | 🟡 Обмежена | 🟢 Нативна |
Коли обирати кожен патерн:
MVC – прототип, MVP продукту, невеликий застосунок з 3-5 екранами, команда початківців або жорсткі дедлайни. MVC iOS – єдиний патерн, для якого Apple надає готові шаблони в Xcode.
MVP – UIKit-проєкт середнього розміру, де важлива тестованість бізнес-логіки, але команда не хоче вивчати реактивне програмування. Добре працює, якщо екранів 10–30 і у кожного екрана своя чітка логіка.
MVVM – активне використання Combine або SwiftUI, складні екрани з кількома джерелами даних, проєкт із розвиненою культурою unit-тестування. Різниця між MVC MVP MVVM стає принциповою, коли застосунок переходить межу в 50+ екранів і кілька команд розробників.
При виборі патерну враховуйте й інші чинники: досвід команди, наявність CI/CD, вимоги до тестованості. Якщо ви плануєте iOS-застосунок з нуля – розробка мобільних застосунків для iOS з досвідченою командою дозволяє обрати архітектуру під конкретні завдання проєкту.
Висновок
MVC – це не «поганий» патерн, це патерн із конкретною сферою застосування. Для швидкого прототипу або невеликого застосунку він залишається оптимальним вибором. Проблеми починаються, коли MVC застосовують до великого проєкту без усвідомлення обмежень – тоді Controller неминуче роздувається. MVP вирішує проблему тестованості без зміни технологічного стеку. MVVM дає максимальну гнучкість при роботі з реактивними фреймворками і SwiftUI. MVC – це базовий патерн iOS-екосистеми, і розуміння різниці між усіма трьома підходами – частина базової грамотності iOS-розробника.
Готовий застосунок зрештою проходить публікацію в App Store – покроковий процес описаний у матеріалі «Як опублікувати застосунок в App Store». Якщо ви шукаєте команду для розробки мобільного застосунку під ключ, архітектурний вибір – одне з перших питань, яке варто обговорити на старті.
Офіційний старт – документація Apple щодо MVC у Cocoa. Для розуміння різниці між патернами в UIKit-контексті – стаття Bohdan Orlov «iOS Architecture Patterns» на Medium. Огляд інструментів для розробки iOS і Android-застосунків – у матеріалі «Топ-10 програм для створення застосунків».


