>> 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.