In the beginning, Apple gave us AppDelegate. And Apple saw that it was good. Then the community spent the next five years telling you to move everything out of it, into coordinators, routers, service layers, and dependency graphs that require a separate diagram just to understand.
I'm here to tell you: they were wrong. The AppDelegate is not a problem to be solved. It is a destination.
"The AppDelegate is the beating heart of your application. Feed it. Nurture it. Let it grow."
The Philosophy of ADD
AppDelegate-Driven Development (ADD — yes, the acronym is intentional and I think it's appropriate) asks a simple question: where does code live? In traditional MVC, the answer is "in lots of places, good luck." In ADD, the answer is AppDelegate.m. Always. Forever.
Core Data stack? AppDelegate. Networking layer? AppDelegate. Push notification handling, deep linking, audio session management, analytics initialization, in-app purchase receipt validation? AppDelegate, AppDelegate, AppDelegate, AppDelegate, AppDelegate, and AppDelegate.
If you can't find it in the AppDelegate, it doesn't exist. This is a feature. This is called discoverability.
Our AppDelegate.m by the Numbers
- Lines of code: 14,229
- Methods: 847
- Private properties: 203
- Compile time: please don't ask
- Engineers who understand all of it: 0 (I wrote most of it and I don't understand it)
What About main.m?
Advanced practitioners have begun migrating certain low-level concerns directly into main.m, before UIApplicationMain is even called. Database migrations. Feature flag bootstrapping. One colleague has his entire authentication flow running in main.m "for performance reasons." He says it's "pre-warming the auth state." I say it's a cry for help, but the app is fast so who's to judge.
int main(int argc, char * argv[]) { // Sync database migrations before UIKit even knows we exist [[MigrationEngine shared] runAllMigrationsOrDie]; // This blocks the main thread. The main thread isn't running yet. It's fine. dispatch_sync(dispatch_get_main_queue(), ^{ /* bold strategy */ }); return UIApplicationMain(argc, argv, nil, @"AppDelegate"); }
Our app launches in under four seconds on an iPhone 5. Not four seconds after the splash screen — four seconds after you plug it in. We are not taking questions.