Reputation: 5491
I am building the state restoration of an iOS app. I currently have
func application(application: UIApplication, viewControllerWithRestorationIdentifierPath identifierComponents: [AnyObject], coder: NSCoder) -> UIViewController? {
guard let controllerIdentifier = identifierComponents.last as? String else {
return nil
}
guard let ctrl = self.window?.rootViewController else {
return nil
}
if controllerIdentifier == "SetupPagesViewController" && ctrl is SetupPagesViewController {
return ctrl
} else if controllerIdentifier == "MainViewController" && ctrl is MainViewController {
return ctrl
}
return nil
}
Where I find that the last line are a bit ugly. I will potentially have more if
s that will always return the controller. I am trying to find a construct where I would not have all those if
s.
I tried with things like:
let checks = [
"SetupPagesViewController": SetupPagesViewController.self,
"MainViewController": MainViewController.self,
]
if let clazz = checks[controllerIdentifier] where ctrl is clazz {
return ctrl
}
But the compiler does not let me. I cannot find a way to store my class
type in order to reuse it in the if
.
Is that possible? How? Thanks
Upvotes: 2
Views: 242
Reputation: 4176
Think this Swifty approach will work for you:
func checkController(controllerIdentifier: String, ctrl: Any) -> UIViewController? {
let objectList: [String:Any.Type] = [
"SetupPagesViewController": SetupPagesViewController.self,
"MainViewController": MainViewController.self
]
let typeOfCtrl: Any.Type = Mirror(reflecting: ctrl).subjectType
if objectList[controllerIdentifier] == typeOfCtrl {
return ctrl as? UIViewController
}
return nil
}
Upvotes: 0
Reputation: 14973
How about this:
typealias NSViewController = Any
class A : NSViewController {}
class B : NSViewController {}
class C : NSViewController {}
let classes : [AnyClass] = [
A.self,
B.self,
C.self
]
func isValid(ctrl: NSViewController, controllerIdentifier: String) -> NSViewController? {
if classes.contains({ controllerIdentifier == String($0) && ctrl.dynamicType == $0 }) {
return ctrl
} else {
return nil
}
}
(the typealias is just to simplify it, doesn't matter really). This works with any type, you also don't need to provide names for the classes because String(someClass)
gives you the name. I used contains
here because I think you just want to check whether it's a valid view controller, which gets returned if it is.
Upvotes: 0
Reputation: 9343
You can use the introspection facilities of the Objective-C runtime (exposed by Foundation) for this, namely, the isKindOfClass
method of NSObject
:
let checks: [String:AnyClass] = [
"SetupPagesViewController": SetupPagesViewController.self,
"MainViewController": MainViewController.self,
]
if let clazz = checks[controllerIdentifier] where ctrl.isKindOfClass(clazz) {
return ctrl
}
Please note that for this to work, the classes have to inherit from NSObject
.
Upvotes: 1