In this tutorial, we take a close look at one of the key methods of the UIApplicationDelegate
protocol, application(_:didFinishLaunchingWithOptions:)
. As the name suggests, this method is called when your app finish launching. It is an ideal moment to set up your app and prepare it for the user.
Application Did Finish Launching with Options
The UIApplication
singleton has a delegate that conforms to the UIApplicationDelegate
protocol. When your app finished launching, the delegate object is notified through the application(_:didFinishLaunchingWithOptions:)
method. Fire up Xcode and create a new project by choosing the App template from the iOS > Application section.
Name your project and set Interface to Storyboard. This is important. I show you how to use the UIApplicationDelegate
protocol in a SwiftUI app later in this tutorial.
Open AppDelegate.swift. AppDelegate
is a class that inherits from UIResponder
and conforms to the UIApplicationDelegate
protocol. The first method of the AppDelegate
class is the application(_:didFinishLaunchingWithOptions:)
method. This method defines two parameters, the UIApplication
instance that sent the message to the app delegate and a dictionary of options. Note that the method returns a Bool
. I talk more about that later in this tutorial.
Launch Options
The dictionary of launch options defines why the app was launched. It is empty if the user tapped the app icon to launch the app. Let me give you an example. If the user taps a remote notification, then the system launches your app. The system populates the dictionary of launch options to inform your app that it was launched due to a remote notification. It is up to your app to use or not use that information.
The dictionary of launch options is also useful if your app is opened in response to the user tapping a URL. Your app can extract the URL from the dictionary of launch options and respond appropriately. That brings us to the return value of application(_:didFinishLaunchingWithOptions:)
.
True or False
The return type of application(_:didFinishLaunchingWithOptions:)
is Bool
. The app delegate uses the return value to inform the system whether it can open the URL that is included in the dictionary of launch options. It is possible that your app is launched in response to the user tapping a URL, but your app decides that it isn't able to handle the URL. In that scenario, the application(_:didFinishLaunchingWithOptions:)
method should return false
. By returning false
, your app won't be opened.
Application Will Finish Launching with Options
There is another method of the UIApplicationDelegate
protocol you need to know about, application(_:willFinishLaunchingWithOptions:)
. As the name suggests, this method is invoked when the app is about to finish launching. The difference is that state restoration hasn't occurred when application(_:willFinishLaunchingWithOptions:)
is invoked. State restoration has completed when application(_:didFinishLaunchingWithOptions:)
is invoked.
Like application(_:didFinishLaunchingWithOptions:)
, the return value of application(_:willFinishLaunchingWithOptions:)
is Bool
. Returning false
means that the app isn't able to handle the URL included in the dictionary of launch options and the app won't open as a result.
SwiftUI and UIApplicationDelegateAdaptor
If you use SwiftUI for your app's user interface, then you may have noticed that your project doesn't have a file with name AppDelegate.swift. No worries, though. You can still take advantage of the UIApplicationDelegate
protocol and hook into the app life cycle. Create a project in Xcode and this time we set Interface to SwiftUI.
Xcode hasn't created a type that conforms to the UIApplicationDelegate
protocol, so let's take care of that first. Create a Swift file and name it AppDelegate.swift. Add an import statement for the UIKit framework. Declare a final class with name AppDelegate
that inherits from NSObject
. This is necessary because the UIApplicationDelegate
protocol inherits from the NSObjectProtocol
protocol. Conform the AppDelegate
class to the UIApplicationDelegate
protocol.
import UIKit
final class AppDelegate: NSObject, UIApplicationDelegate {
}
Implement the application(_:didFinishLaunchingWithOptions:)
method. We add a print statement and return true
in the body of the application(_:didFinishLaunchingWithOptions:)
method.
import UIKit
final class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
print("APPLICATION DID FINISH LAUNCHING")
return true
}
}
Creating the AppDelegate
class is the first step. Open NotesApp.swift. The file in your project may be named differently but it should end in App.swift. It defines a struct that conforms to the App
protocol.
We declare a private, variable property with name appDelegate
of type AppDelegate
. How does SwiftUI know that it should set the AppDelegate
instance as the delegate of the UIApplication
singleton? We do that by prefixing the declaration of the appDelegate
property with the UIApplicationDelegateAdaptor
property wrapper. SwiftUI takes care of the rest. It instantiates the AppDelegate
instance and sets it as the delegate of the UIApplication
singleton.
import SwiftUI
@main
struct NotesApp: App {
// MARK: - Properties
@UIApplicationDelegateAdaptor private var appDelegate: AppDelegate
// MARK: - App
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
Let's give it a try. Build and run the app in the simulator. You should see the output of the print statement we added to the application(_:didFinishLaunchingWithOptions:)
method in the console.
APPLICATION DID FINISH LAUNCHING
Keep It Simple and Fast
The methods of the UIApplicationDelegate
protocol are executed on the main thread, so it is crucial that you keep these methods simple and lightweight. If it takes too long for your app to launch, the system will simply terminate your app. That is something you need to avoid at all cost. It is fine to defer some work to a later point in time, after your app has launched. Nobody likes apps that take forever to launch. Right?