iOS
App Delegate
ViewController
Method Calling
Swift Programming

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:

swift
1import UIKit
2
3@main
4class AppDelegate: UIResponder, UIApplicationDelegate {
5    func refreshRemoteConfig() {
6        print("Refreshing remote config")
7    }
8}
9
10final class HomeViewController: UIViewController {
11    @IBAction func didTapRefresh(_ sender: UIButton) {
12        if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
13            appDelegate.refreshRemoteConfig()
14        }
15    }
16}

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:

swift
1import UIKit
2
3@main
4class AppDelegate: UIResponder, UIApplicationDelegate {
5    func registerForPushNotifications() {
6        UIApplication.shared.registerForRemoteNotifications()
7    }
8}

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.

swift
1import UIKit
2
3final class SessionService {
4    func refreshSession() {
5        print("Refreshing session")
6    }
7}
8
9final class SettingsViewController: UIViewController {
10    var sessionService = SessionService()
11
12    @IBAction func didTapRefresh(_ sender: UIButton) {
13        sessionService.refreshSession()
14    }
15}

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:

objective-c
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
[appDelegate refreshRemoteConfig];

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 AppDelegate just because it is globally reachable.
  • Reaching into appDelegate.window in 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 AppDelegate just 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.

Course illustration
Course illustration

All Rights Reserved.