Search code examples
iosswiftuiappdelegate

SwiftUI 2 accessing AppDelegate


I did a small prototype which uses Firebase Cloud Messaging and the new SwiftUI 2 app life cycle. I added a custom AppDelegate via @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate and disabled method swizzeling for FCM to work. Everything is working as expected.

Today a colleague asked me, if one can get that delegate object via UIApplication.shared.delegate. So I gave it a shot and noticed that there seems to be two different AppDelegate objects:

po delegate prints:

<MyProject.AppDelegate: 0x6000009183c0>

where as po UIApplication.shared.delegate prints:

▿ Optional<UIApplicationDelegate>
  ▿ some : <SwiftUI.AppDelegate: 0x600000b58ca0>

Now I'm wondering what is the correct way of accessing the AppDelegate? Should one get it via an @EnvironmentalObject and pass it along all views? Or use the old fashioned way via UIApplication? Additionally I would like to understand why I end up with two AppDelegates.


Solution

  • Your MyProject.AppDelegate is not direct UIApplicationDelegate, it is transferred via adapter to internal private SwiftUI.AppDelegate, which is real UIApplicationDelegate and which propagates some delegate callback to your instance.

    So the solution might be:

    1. Use @EnvironmentalObject if you need access to your MyProject.AppDelegate only in SwiftUI view hierarchy (for this AppDelegate must conform to ObservableObject).

    2. Add and use MyProject.AppDelegate static property which is initialized with object created via adapter, like

    class AppDelegate: NSObject, UIApplicationDelegate {
        static private(set) var instance: AppDelegate! = nil
        
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
            AppDelegate.instance = self    // << here !!
            return true
        }
    }
    

    now everywhere in your code you can access your delegate via AppDelegate.instance.