They ask: "How does Apple's MVC differ from textbook MVC, and what does 'Massive View Controller' actually mean?"
Textbook MVC keeps Controller as a thin coordinator between an independent Model and View that don't know about each other. Apple's UIViewController collapses that boundary: it's simultaneously the controller and a huge chunk of view-management responsibility (layout, lifecycle, UITableViewDataSource/Delegate conformance), which is exactly why the pattern gets nicknamed "Massive View Controller" in practice — the natural home for network calls, business logic, formatting, and UI code all being the same object.
The Passive vs Active Model distinction matters here: a passive model is dumb data with no behavior of its own — the controller drives everything, including update notifications. An active model can notify observers of its own changes (via KVO, NotificationCenter, or Combine), which is what lets a view controller stay reactive instead of manually polling.
// Massive VC symptom: networking, parsing, and UI logic all in the controller
class ProfileViewController: UIViewController, UITableViewDataSource {
func viewDidLoad() {
URLSession.shared.dataTask(with: url) { data, _, _ in
self.user = try? JSONDecoder().decode(User.self, from: data ?? Data())
DispatchQueue.main.async { self.tableView.reloadData() }
}.resume()
}
}
The fix isn't abandoning MVC wholesale — it's pulling networking, parsing, and formatting logic out into dedicated services/view models, leaving the controller genuinely thin: wiring views to data and forwarding user actions. LVC ("Lean View Controller") is the informal name for that disciplined version of the same pattern.
Say it: "Apple's MVC isn't broken, it's just that UIViewController absorbs view and controller responsibilities by design — Massive View Controller is what happens when you also let it absorb networking and business logic; the fix is extracting those into services, not switching architectures."
Red flag: Blaming "MVC" itself for a bloated view controller. The pattern didn't put the networking code there — nothing enforced the extraction, and that's a discipline gap, not an architectural inevitability.