When working with CoreData, we need access to the shared store which is available via the AppDelegate. To obtain a reference to the AppDelegate we can get it by doing the following:
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate
else {
return
}
Why do we have to be so safe when downcasting to the Appdelegate? Can the downcast ever fail for some reason and if so, why?
I have looked around and can't find a reason as to why we write this code, and wanting to know why I write things will help!
Optional downcasting to AppDelegate
(actually to the class representing the application delegate class) will never fail because the application won't even launch if the application delegate class was missing.
You can 100% safely write
let appDelegate = UIApplication.shared.delegate as! AppDelegate
Many people suffer from exclamationmarkophobia 😉 and argue that all exclamation marks are evil and you always have to guard
any optional. This is wrong. The world is not only black and white. There are many cases where forced unwrapping an optional is safe like in this particular case.
Adding the @UIApplicationMain
attribute to a class
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate { ... }
is equivalent to calling UIApplicationMain()
in "main.swift"
with "AppDelegate" as the name of the class from which the application delegate is instantiated:
UIApplicationMain(
CommandLine.argc,
UnsafeMutableRawPointer(CommandLine.unsafeArgv)
.bindMemory(
to: UnsafeMutablePointer<Int8>.self,
capacity: Int(CommandLine.argc)),
nil,
NSStringFromClass(AppDelegate.self)
)
(compare e.g. What does "@UIApplicationMain" mean? and Subclass UIApplication with Swift).
With either method, an instance of the AppDelegate
class is created
and passed as delegate to the application object. So yes,
let appDelegate = UIApplication.shared.delegate as! AppDelegate
is safe.
But note that there is nothing special about the class name "AppDelegate", this is just convention. You can define the application delegate as
@UIApplicationMain
class MyFantasticAppDelegate: UIResponder, UIApplicationDelegate { ... }
in which case it of course would be
let appDelegate = UIApplication.shared.delegate as! MyFantasticAppDelegate
So the precise statement would be
Casting
UIApplication.shared.delegate
to the type of the class defined as application delegate cannot fail.
By convention, that type is AppDelegate
, but it doesn't have to be.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With