2

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 use window as a non-optional UIWindow.

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?

Senseful
  • 86,719
  • 67
  • 308
  • 465
  • 1
    Also a duplicate of http://stackoverflow.com/questions/28901893/why-is-main-window-of-type-double-optional. – Martin R Nov 19 '15 at 22:09
  • your mistake is that `Optional.None` (nil) is different from `Optional.Some(Optional.None)` (not nil). Which is like saying a missing box is different from a box that doesn't have second, expected box inside it. – Alex Brown Nov 20 '15 at 07:23

1 Answers1

4

one possible solution...

if let window = application.delegate?.window ?? nil {
  print(window.frame)
}
André Slotta
  • 13,774
  • 2
  • 22
  • 34