If I attempt to compile the following code, it will fail on the print
line.
func foo(application: UIApplication) {
if let window = application.delegate?.window {
print(window.frame) // SYNTAX ERROR
}
}
The reason is that window is of type UIWindow?
, not UIWindow
:
error: value of optional type 'UIWindow?' not unwrapped; did you mean to use '!' or '?'?
I can fix it by doing this:
func foo(application: UIApplication) {
if let window = application.delegate?.window {
if let window = window {
print(window.frame)
}
}
}
However, that adds more lines of code, and it seems like it shouldn't be necessary. I thought the if let <variable> = <value>
was supposed to only execute its body if window
was found to be non nil
.
In other words, I was hoping it would use this kind of logic:
- If
application.delegate = nil
, don't execute the block. - If
application.delegate.window = nil
, don't execute the block. - If
application.delegate.window != nil
, execute the block and allow me to usewindow
as a non-optionalUIWindow
.
Why is if let window = application.delegate?.window
defining window
as an optional? Is there any way I can get it to behave like the second snippet above by adding little or no code?
Note: I do not want to use print(window?.frame)
because printing is only an example. I actually have much more code and don't want to use the null object pattern. I want it to really be defined as a non-optional.
Update: If I use let test = application.delegate?.window
, I see that the type is UIWindow??
, or a double optional. This explains why I do need the second let statement. So I guess my question is now what is the most concise way to unwrap a double optional?