iOS - Calling App Delegate method from ViewController
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
You can call an AppDelegate method from a view controller by getting the shared application delegate and casting it to your app's delegate type. That works, but whether it is a good idea depends on what the method does.
If the method handles true app-wide behavior, such as push registration or global startup state, calling through the app delegate can be reasonable. If it is ordinary business logic, move that logic into a separate service instead of turning AppDelegate into a global utility object.
Call the App Delegate Directly
The direct pattern in Swift looks like this:
This is the usual answer to the mechanical question. UIApplication.shared.delegate gives you the app delegate instance, and the cast lets you call your custom method.
Use This Only for App-Level Responsibilities
Just because you can call the app delegate does not mean every shared method belongs there. AppDelegate is primarily for application lifecycle responsibilities such as launch configuration, notification registration, and integration setup.
For example, a method like registerForPushNotifications() might still fit there:
Calling that from a controller is understandable because it is tightly related to application-level capabilities.
By contrast, methods like calculateCartTotal() or loadUserProfile() do not belong in the app delegate. Those should live in dedicated types that can be reused and tested directly.
Prefer a Service for Shared Logic
A cleaner architecture is to move shared behavior into a service object and inject or reference that service where needed.
This avoids coupling your screen code to UIApplication. It also makes unit tests much simpler because you can replace the service with a mock or stub.
Scene-Based Apps Change the Tradeoffs
In modern iOS apps, especially those using scenes, not every globally accessible value lives in AppDelegate anymore. Window and UI state often belong to scene delegates or coordinators.
That means old code patterns such as reaching into appDelegate.window are often wrong in multi-window apps. If your controller needs scene-specific UI coordination, the app delegate is usually the wrong place to fetch it from.
So the safe rule is:
- app-wide lifecycle logic may live in
AppDelegate - scene-specific UI logic should not
- reusable business logic belongs in services or managers
Calling from Objective-C
If the project is Objective-C, the same idea applies:
This is still straightforward, but the architectural warning remains the same.
Decide Based on Ownership
A good design question is: who should own this behavior? If the answer is "the application as a whole," the app delegate may be acceptable. If the answer is "this feature," "this screen," or "this domain service," then the method should almost certainly live somewhere else.
That ownership decision matters more than the syntax. Most codebases get into trouble here not because the cast is wrong, but because too much unrelated logic accumulates in the app delegate over time.
Common Pitfalls
- Putting general business logic in
AppDelegatejust because it is globally reachable. - Reaching into
appDelegate.windowin scene-based apps where the window belongs elsewhere. - Accessing the app delegate from many controllers and creating tight global coupling.
- Forgetting that direct delegate access makes testing harder than service injection.
- Using the app delegate as a grab bag instead of keeping clear ownership boundaries.
Summary
- You can call an app delegate method with
UIApplication.shared.delegate as? AppDelegate. - This is reasonable for true app-level concerns such as registration or launch-related behavior.
- Do not put ordinary feature logic in
AppDelegatejust because it is easy to access. - Prefer service objects for reusable or testable shared behavior.
- In scene-based apps, remember that not all global-looking UI state belongs to the app delegate.

