AppDelegate can be nil?

Hi there!


Is it thinkable, that in an iOS App the AppDelagate can be nil?

Suppose we have an view controller that needs a reference to the AppDelegate and tests the existence of the delagate like this:


...
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
     fatalError("no Application Delegate found")
}
...


I'm not sure about that, but when no delegate exists it is not possible to reach code in any view controller or framework or whatsoever because the App should crash before any other part of the App can be executed. Therefore the test above is unnecessary.


Question: Is that right?


Regards!

Post not yet marked as solved Up vote post of strike Down vote post of strike
4.1k views

Replies

I have always thought appDelegate can't be nil.


May have a look at this discussion :

h ttps://stackoverflow.com/questions/17148046/setting-appdelegate-shared-instance-to-nil-does-not-create-warning-or-crash

>> I have always thought appDelegate can't be nil.


It depends what you mean. It's extremely difficult (perhaps impossible, I don't know) to start an application without an app delegate object, because the delegate is typically created for you. However, you can set the delegate to nil later.


Either way (no delegate initially, or nil delegate later), the app isn't going to crash, because this is a standard delegate pattern. When the owner wants to invoke a delegate method(UIApplication.shared), it always checks that the delegate exists, and that it implements the method. If not, it doesn't invoke the method.


Note that there's no difference between the delegate being nil, and the delegate being non-nil but not implementing any methods. All app delegate methods are optional.


>> Question: Is that right?

No. This expression:


     UIApplication.shared.delegate as? AppDelegate


can be nil for two reasons:


1. The application has no delegate (or it had one earlier, but the delegate was set to nil).


2. The delegate's type is not "AppDelegate".


In normal cases, neither of these things should be true, so it's a programming error if the expression is true. In that case, you do want your app to crash, but it's slightly better to force the crash this way:


     let appDelegate = UIApplication.shared.delegate as! AppDelegate


Why is that better than a 'guard' check? Because it's clearer and more concise for someone reading your code.

I actually ran into an example of UIApplication.shared.delegate being nil today.

During the init of your app delegate, UIApplication.shared.delegate is nil. So if something needs to access the app delegate immediately after super.init() there's a possibility its still nil.

For me, I populated my dependency root for dependency injection here.

I added a line of code to one of my services that needed to access the app delegate and it was nil.

Other than this,

I can't think of any other possible times that it would be nil.