How to use UIApplicationDelegateAdaptor

With SwiftUI 2.0, UIApplicationDelegate is a thing of the past… well, maybe not. While the new App protocol and friends provide great, declarative abstractions over UIKit/AppKit app lifecycle APIs, their shortcomings may become evident when faced with complex scenarios - such as handling remote notifications, or handling shortcuts.

Fortunately, SwiftUI 2.0 provides us with a bridge between our two worlds:

/// A property wrapper that is used in `App` to provide a delegate from UIKit.
@available(iOS 14.0, tvOS 14.0, *)
@available(OSX, unavailable)
@available(watchOS, unavailable)
@propertyWrapper public struct UIApplicationDelegateAdaptor<DelegateType> : DynamicProperty where DelegateType : NSObject, DelegateType : UIApplicationDelegate {

    /// The underlying delegate.
    public var wrappedValue: DelegateType { get }

    /// Creates an `UIApplicationDelegateAdaptor` using a UIKit Application
    /// Delegate.
    ///
    /// The framework will initialize the provided delegate and manage its
    /// lifetime, calling out to it when appropriate after performing its
    /// own work.
    ///
    /// - Parameter delegate: the type of `UIApplicationDelegate` to use.
    public init(_ delegateType: DelegateType.Type = DelegateType.self)
}

Now, how do we use it?

Take the stock boilerplate for a cross-platform SwiftUI app:

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

If we wanted this app to use a typical UIApplicationDelegate while still retaining a declarative, SwiftUI entry point - we could rewrite it like so:

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        print("Yay")

        return true
    }
}

@main
struct MyApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

Run this code - and your app will print Yay.

That’s it!

Note that certain delegate functions, such as applicationDidFinishLaunching, do not seem to work with this approach.

 
7
Kudos
 
7
Kudos

Now read this

Losing My Touch

I’d hate to think that I’m losing my touch, With reality, with thoughts—it’s just too much. The dynamics, to me, are quite unclear Who, or what, am I supposed to be here? I hate these emotions that I suddenly feel I’m aware of it now, I’... Continue →