Initialization order of SwiftUI Application + @UIApplicationDelegateAdaptor

In my application initializer, I set a property on ApplicationDelegate. It is a reference to my data controller that manages access to many things (core data model). It gets passed in there to handle launch keys and pushes, and is relied upon as a required dependency to many services--namely push, navigation actions (quick look, Siri intents, etc.).

In summary, I want to clean up and move some initialization code from my application initializer (tons of compiler directives for multi targets, watch, app, etc.) to the respective application delegates. BUT this requires an assumption that didFinishLaunching will be called after a property is injected into app delegate. Is this a safe assumption to make?

I have observed the didFinishLaunching getting invoked only AFTER the initializer of Application completes. Can this be relied upon in terms of dependency injection?

Can this order be assumed?

  1. Application init
  2. Property assignment on app delegate within app init
  3. App delegate init
  4. Property is set (didSet fires)
  5. App initialization complete, return
  6. Delegate fires willFinishLaunching
  7. Delegate fires didFinishLaunching
  8. Other delegate methods fire accordingly

I assume that the implementation of UIApplicationDelegateAdaptor under the hood is similar to the Coordinators in UIViewRepresentable where as soon as you try to access / assign something on it, then it constructs the object and assigns an instance to the property wrapper.

Additionally, if it hadn't already been initialized, because it DOES need to call delegate callbacks, the system will invoke it had you not already assigned a property to initialize it.

Replies

Don't overthink the architecture. You should not be using or depending on didSet. The documentation states then once an application delegate also conforms to the ObservableObject type it is automatically available to the entire SwiftUI Application because it places it into the Environment via the EnvironmentObject on your behalf. So move away from the swift didSet/willSet paradigm for property observations and move toward combine or publishers in the form of making the properties of interest into annotated @Published type. Then anywhere in your swiftUI code that needs access to some kind of data from the app delegate will automatically have it via the following pattern.

@EnvironmentObject private var appDelegate: MyAppDelegate

Read here: https://developer.apple.com/documentation/swiftui/uiapplicationdelegateadaptor

  • Thanks @MobileTen for the link. Ironically, when conforming the ApplicationDelegate to ObservableObject, its initializer gets hit first, then the application struct's; the order is changed. No conformance it is Application init THEN ApplicationDelegate.

    I haven't found documentation yet on the property wrappers describing initialization differences if the wrapped value conforms to ObservableObject or not.

Add a Comment