Why is main window of type double optional?

@matt has the details, but there is a (somewhat horrible, somewhat awesome) workaround. (See edit below, though)

let window = app.delegate?.window??.`self`()

I will leave the understanding of this line of code as an exercise for the reader.

OK, I lie, let’s break it down.

app.delegate?.window

OK, so far so good. At this point we have the UIWindow?? that is giving us a headache (and I believe is a bug in Swift disconnect between Swift and Cocoa). We want to collapse it twice. We can do that with optional chaining (?.), but that unwraps and rewraps, so we’re back where we started from. You can double-optional-chain, though, with ??. which is bizarre, but works.

That’s great, but ?? isn’t a legal suffix operator. You have to actually chain to something. Well, we want to chain back to itself (i.e. “identity”). The NSObject protocol gives us an identity method: self.

self is a method on NSObject, but it’s also a reserved word in Swift, so the syntax for it is `self`()

And so we get our madness above. Do with it as you will.

Note that since ??. works, you don’t technically need this. You can just accept that view is UIWindow?? and use ??. on it like view??.frame. It’s a little noisy, but probably doesn’t create any real problems for the few places it should be needed.

(*) I used to think of this as a bug in Swift, but it’s not fixable directly by optional chaining. The problem is that there is no optional chaining past window. So I’m not sure where the right place to fix it is. Swift could allow a postfix-? to mean “flatten” without requiring chaining, but that feels odd. I guess the right operator would be interrobang delegate?.window‽ 😀 I’m sure that wouldn’t cause any confusion.

EDIT:

Joseph Lord pointed out the better solution (which is very similar to techniques I’ve been using to avoid trivial if-let, but hadn’t thought of this way before):

let window = app.delegate?.window ?? nil // UIWindow?

I agree with him that this is the right answer.

Leave a Comment