🍫 CocoaPatterns — iOS & Mac Development Since 2009 RSS
🍫 CocoaPatterns
Because someone has to write this stuff down
"We ship apps. Sometimes they even work."

AppDelegate-Driven Development: One File to Rule Them All

Why distribute logic across dozens of files when one beautiful god-object can hold everything?

BK
Brad Kowalski
@bradkow_ios · CocoaPatterns

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.

💡 ADD Principle #1

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.

3 Comments — Powered by Disqus
SK
santiagok_mob · 1 day ago
14,229 lines. I feel seen. Ours is 11k and everyone acts like I personally wronged them.
BK
bradkow_iosAuthor · 1 day ago
@santiagok_mob 11k is just getting started. Stay the course.
RN
r_narayanan_dev · 20 hours ago
"The main thread isn't running yet. It's fine." I need this on a poster.