SuperDelegate: The Better App Delegate

A Swift framework that provides a consistent and bug-free App Delegate API across all iOS SDKs.

A Swift framework that provides a consistent and bug-free App Delegate API across all iOS SDKs.

Written by Dan Federman.

We deserve better

If you’ve written an iOS application, you’ve implemented a UIApplicationDelegate. UIApplicationDelegate is central to how our apps interact with iOS, but the API is incredibly idiosyncratic. When an app is launched due to a Quick Action via 3D Touch, iOS will notify the app in both the application(:FinishLaunching:) methods and *application(:performActionForShortcutItem:completionHandler:), unless the app signals to iOS that it handled the shortcut in application(_:willFinishLaunching:) by returning false. Handling URLs (and push notifications, and user activity items) is even worse. When an app is launched with an NSURL it’ll be notified in the application(:*FinishLaunching:) *methods as well as the *application(:openURL:options:) method, and there’s no way to prevent *application(:openURL:options:) *from being called even if the URL is handled during *application(:FinishLaunching:).

Also, key questions are left unanswered by the UIApplicationDelegate protocol. Want to know if a customer tapped on a push notification or if the notification was delivered due to a content-available flag? Or if calling *registerUserNotificationSettings(_:) *will silently work without prompting a customer for access? Each app needs to engineer their own solutions to these problems.

Breaking lifecycle changes

To make matters worse, each iOS release and SDK can introduce undocumented breaking changes into the application lifecycle. On iOS 8.4, application(_:handleWatchKitExtensionRequest:reply:) is called before application(_:didFinishLaunching:), but this isn’t true on iOS 8.0–8.3! iOS 8.0–8.2 will crash if an app tries to load UI while the app is in the background, unless the app forces the creation of a sharedCIContext within application(_:didFinishLaunching:). The list goes on.

Each time Apple introduces a new quirk in the application delegate contract, every app in the app store has to find the quirk and work around it to ensure their customers are not negatively impacted.

Let’s work together

Instead of making each developer learn about these quirks the hard way, let’s create a central repository of UIApplicationDelegate tribal knowledge. Enter SuperDelegate. SuperDelegate takes everything we at Square learned about the UIApplicationDelegate and turns it into a clean application delegate API. SuperDelegate is stable across all versions of iOS 8 and 9 and handles boilerplate app delegate code for you. It’s written entirely in Swift, and we’re open sourcing it today.

SuperDelegate ensures that unique notifications, URLs, user activity items, and shortcuts are be delivered to an app only once. After an app registers for user notifications the first time, SuperDelegate automatically registers for user notifications on *application(_:willEnterForeground:) *so that an app always knows the current state of push notification permissions. When an app receives a push notification, SuperDelegate tells the app whether the customer tapped on it. SuperDelegate guarantees that it will invoke *setupApplication() and loadInterface(launchItem:) *prior to forwarding any other app delegate API calls. Adopting this clean, surprise-free API makes implementing new iOS features significantly easier and faster, and will fix bugs in your existing implementation you didn’t even know you had.

We’re actively working to adopt Swift 3.0 and the iOS 10 SDK, and we’re doing it in the open. As we find new eccentricities in the iOS 10 API, we’ll file issues and update our develop/v0.9 branch. We welcome you to follow along, and encourage you to let us know what you find in the API! Dan Federman *Follow the latest activity of Dan Federman on Medium. 57 people are following Dan Federman to see their stories and…*

Table Of Contents