In Objective-C, it's possible to specify a class conforming to a protocol as a method parameter. For example, I could have a method that only allows a UIViewController
that conforms to UITableViewDataSource
:
- (void)foo:(UIViewController<UITableViewDataSource> *)vc;
I can't find a way to do this in Swift (perhaps it's not possible yet). You can specify multiple protocols using func foo(obj: protocol<P1, P2>)
, but how do you require that the object is of a particular class as well?
In Swift, protocols can inherit from one or more additional protocols. Let's see how and why to use it. Here we have a User protocol, this protocol will be getting bigger each time we add a new User requirement into it.
A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements.
Mitrenegades solution is to use an objective-c protocol, is one way, but if you want a swift protocol, then the other would be to refactor the code so as to not use the objective-c class directly, but instead use the protocol (e.g. some protocol based factory pattern). Either way may be appropriate for your purposes.
You can define foo
as a generic function and use type constraints to require both a class and a protocol.
Swift 4
func foo<T: UIViewController & UITableViewDataSource>(vc: T) { ..... }
Swift 3 (works for Swift 4 also)
func foo<T: UIViewController>(vc:T) where T:UITableViewDataSource { .... }
Swift 2
func foo<T: UIViewController where T: UITableViewDataSource>(vc: T) { // access UIViewController property let view = vc.view // call UITableViewDataSource method let sections = vc.numberOfSectionsInTableView?(tableView) }
In Swift 4 you can achieve this with the new & sign:
let vc: UIViewController & UITableViewDataSource
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With