The property window
of UIApplicationDelegate
protocol is declared like this:
optional var window: UIWindow? { get set }
That means that it is an optional property (in the sense that "the class implementing the UIApplicationDelegate
protocol is not requested to implement/have this property", like when you have @optional
in Objective-C), and that property is of optional type Optional<UIWindow>
(or UIWindow?
).
That's why you have the double-optional type in the end, because that window
property may or may not be implemented in realDelegate, and if it is, it will be itself of type Optional<UIWindow>
/UIWindow?
.
So basically what you want is to return the window
property of your realAppDelegate
… only if that realAppDelegate
decided to declare that property itself (which it isn't requires to do, as it's optional var
).
- If the
realAppDelegate
did not implement window
itself, you probably intend to return a nil
UIWindow?
as a result.
- If your
realAppDelegate
did actually implement the window
property, then you need to return it as is (wether this implementation returns an actual UIWindow
or a nil
one).
The easiest way to do that is to use the nil-coalescing operator ??
in Swift. a ?? b
meaning that "if a is non-nil, then return a, but if a is nil, return b" (where if a
is of type T?
, then the whole expression is expected to return an object of type T
, where in your case T
is the type UIWindow?
).
var window: UIWindow? {
get {
// If realAppDelegate.window (of type UIWindow??) is not implemented
// then return nil. Otherwise, return its value (of type UIWindow?)
return realAppDelegate.window ?? nil
// That code is equivalent (but more concise) to this kind of code:
// if let w = realAppDelegate.window { return w } else return nil
}
...
}
To implement the setter, that's another problem. According to this SO answer, directly accessing to the setter of an optional property of a protocol doesn't seem to be possible. But you can imagine a hack to workaround this, by declaring another protocol that makes this window
property requirement mandatory, then try to cast to it in the setter:
@objc protocol UIApplicationDelegateWithWindow : UIApplicationDelegate {
var window: UIWindow? { get set }
}
class AppDelegateWrapper : UIApplicationDelegate {
...
var window: UIWindow? {
get {
return realAppDelegate.window ?? nil
}
set {
if let realAppDelWithWindow = realAppDelegate as? UIApplicationDelegateWithWindow
{
// Cast succeeded, so the 'window' property exists and is now accessible
realAppDelWithWindow.window = newValue
}
}
}
...
}