As of Swift 4:
Thanks to SE-0156:
The proposal keeps the existing &
syntax but allows one of the elements to be either AnyObject
or of class type. The equivalent to the above Objective-C types would look like this:
AnyObject & Protocol1 & Protocol2
Base & Protocol
As in Objective-C, the first line is an existential of classes which conform to Protocol1
and Protocol2
, and the second line is an existential of subtypes of Base
which conform to Protocol
.
.. we can now declare:
var v1 : UIViewController & P1 // UIViewController which conforms to `P1`
Prior Swift 4:
There is no way to directly do that. You have to either declare v1
as UIViewController
or as P1
, and then use casting (as
) in order to get to the other functionality.
Closest you can get what you want is with generics. For example:
func testGeneric<T: UIViewController where T: P1>(input: T) {
input.f1()
}
For example, if your case is to have a delegate which is both controller by inheritance and a delegate by protocol implementation, then you can go along these lines:
protocol Delegate: class {
func doDelegate()
}
class Controller {
func doController() {
print("Controller")
}
}
class ConcreteController: Controller, Delegate {
func doDelegate() {
print("Delegate")
}
}
class View {
private weak var controller: Controller? = nil
private weak var delegate: Delegate? = nil
func setDelegateController<T: Controller where T: Delegate>(delegateController: T?) {
controller = delegateController
delegate = delegateController
}
func test() {
controller?.doController()
delegate?.doDelegate()
}
}
And to test this out:
let view = View()
let controller = ConcreteController()
view.setDelegateController(controller)
view.test() // This will print:
// Controller
// Delegate