To Get the rootViewController in Objective-c you can use the below line of code
[[[UIApplication sharedApplication] delegate] window].rootViewController
I tried to do the same in swift
UIApplication.sharedApplication().delegate?.window?.rootViewController
But I got this error
'UIWindow?' does not have a member named 'rootViewController'
And the suggestion says that you have to unwrap UIWindow twice UIWindow??
to be
UIApplication.sharedApplication().delegate?.window??.rootViewController
My Question is: Why do I need to unwrap the window twice ?
.
.
I have looked in the API and found that
protocol UIApplicationDelegate : NSObjectProtocol {
optional var window: UIWindow? { get set }
}
The window has one optional
class UIWindow : UIView {
var rootViewController: UIViewController?
}
Also the rootViewController has one optional
.
.
I thought may be because UIWindow in UIApplicationDelegate protocol has optional
and UIWindow?
so I tried the below in Playground
@objc protocol MyApplicationDelegate {
optional var myWindow: MyWindow? { get set }
}
class MyWindow : NSObject {
var rootViewController: Int?
init(number: Int) {
rootViewController = number
}
}
class MyAppDelegate: MyApplicationDelegate {
var myWindow: MyWindow?
init() {
myWindow = MyWindow(number: 5)
}
}
let myDelegate = MyAppDelegate()
println(myDelegate.myWindow?.rootViewController)
However I can get myWindow
with one optional and can successfully log '5'
What am I missing here?
Well; I found the problem with my example
In my example I'm creating object from MyAppDelegate
directly which will sure have myWindow
property as I'm defining it
Changing the example to be the following
@objc protocol MyApplicationDelegate {
optional var myWindow: MyWindow? { get set }
}
class MyWindow : NSObject {
var rootViewController: Int?
init(number: Int) {
rootViewController = number
}
}
class MyAppDelegate: MyApplicationDelegate {
var myWindow: MyWindow?
init() {
myWindow = MyWindow(number: 5)
}
}
class MyApplication: NSObject {
var myDelegate: MyApplicationDelegate
override init() {
myDelegate = MyAppDelegate()
}
}
let myApplication = MyApplication()
println(myApplication.myDelegate.myWindow??.rootViewController)
I needed to add another class MyApplication
that has a property conform toMyApplicationDelegate
So I was able to use myWindow?? first unwrapping for the optional
part in the protocol and second one is for the optional declaration in the variable UIWindow?