I was reading Apple docs, when I found this sentence:
The
AppDelegate
class contains a single property:window
.
va
You may not always need it. For example, when these two methods are called :
application(_:performFetchWithCompletionHandler:)
application(_:handleEventsForBackgroundURLSession:completionHandler:)
your app will not be shown to the user, so there is no need for a window
.
As always, more in the docs
Now, I'm not sure that this is the inherent reason, but it seems as a good enough possibility (at least for me). Though if someone is able to provided some more information, I'd gladly learn some more also.
When you close your application, your app can still receive silentNotifications or download data in the background, track your location, play music, etc.
In the images below, the encircled red are for when your app is still doing something, however it is no longer on the screen. It's in the background, so
AppDelegate
doesn't need a window
anymore. As a result it will be set to nil
FWIW, the code below won't make the app launch with vc
.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let vc = ViewController()
window?.rootViewController = vc
window?.makeKeyAndVisible()
return true
}
Why it doesn't work? Because the window
property is an optional—initially set to nil.It needs to be instantiated
The code below will work
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let vc = ViewController()
window = UIWindow(frame: UIScreen.main.bounds) // Now it is instantiated!!
window?.rootViewController = vc
window?.makeKeyAndVisible()
return true
}
It becomes more obvious when you create the window programmatically instead of using a main storyboard, which automatically sets the window
property.
You may not want to or not be able to create the window immediately when your delegate object (AppDelegate
in your case) is created. Usually you don't need to create the window and set the property until application(_:didFinishLaunchingWithOptions:)
was called. So until the window is created and the property is set it will be nil
.
Like Losiowaty already stated this is also the case when the app is started but not displayed to the user - e.g. when just processing location updates or other information in the background.
If the property would be non-optional then you would be forced to create the window at the moment you create your AppDelegate
object which is neither desired nor necessary.