Reputation: 11710
Let's say I have a protocol that looks like this:
protocol Foo {
var bar: Bool { get set }
}
Now I have my view controller that conforms to the Foo protocol;
class FooViewController: UIViewController, Foo {
...
}
In another class I want to do something like this:
class FooClass {
var viewController: UIViewController? // this should conform to Foo protocol
func setViewController(viewController: UIViewController) {
if let fooVC = viewController as? Foo {
// viewController implements Foo protocol
self.viewController = fooVC
} else {
print("ViewController does not conform to Foo protocol")
}
}
}
In Objective-C I would have a reference that looks like: UIViewController<Foo> *vc
saying that vc is an object of class UIViewController conforming to Foo protocol. Is there a Swift equivalent?
EDIT: I guess it's not possible :(
Upvotes: 4
Views: 1336
Reputation: 255
This is the solution:
typealias FooController = UIViewController & Foo
class FooClass {
var viewController: FooController?
func setViewController(viewController: FooController) {
self.viewController = viewController
}
}
Upvotes: 3
Reputation: 1301
Warning: This solution may become very painful.
As a workaround, you may use protocol compositions and eventually extensions.
In your example you could be interested only in UIResponder
protocol methods which UIViewController
conforms to.
typealias FooController = protocol<UIResponder, Foo>
class FooClass {
var viewController: FooController?
func setViewController(viewController: FooController) {
// viewController implements UIResponder and Foo protocols
}
}
But UIViewController
has properties and methods that does not conforms to any protocol. In this case, you could make a protocol containing the methods that you want and extend UIViewController
.
protocol ViewEvent {
func viewWillAppear(animated: Bool)
func viewDidAppear(animated: Bool)
func viewWillDisappear(animated: Bool)
func viewDidDisappear(animated: Bool)
}
extension UIViewController: ViewEvent {}
typealias FooController = protocol<UIResponder, ViewEvent, Foo>
Upvotes: 3
Reputation: 59496
I see what you mean.
I don't think you can declare a variable of a given class type and conform to a protocol.
However if you just need to check whether viewController
does conform to the Foo
protocol (and you don't really need to use the bar property declared in Foo
) then you could do this.
func setViewController(viewController: UIViewController) {
if viewController is Foo {
self.viewController = viewController
} else {
print("ViewController does not conform to Foo protocol")
}
}
Upvotes: 1
Reputation: 3661
You can define as viewController:Foo?
Based on our comment you should used if let fooVC = viewController as? FooViewController
. If you are optional binding the viewController to Foo then assigning it to a UIViewController instance will not work.
Upvotes: 0