Class conforming to protocol as function parameter in Swift

In Swift 4 you can achieve this with the new & sign:

let vc: UIViewController & UITableViewDataSource

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)
}

The Swift book documentation suggests that you use type constraints with a where clause:

func someFunction<C1: SomeClass where C1:SomeProtocol>(inParam: C1) {}

This guarantees that "inParam" is of type "SomeClass" with a condition that it also adheres to "SomeProtocol". You even have the power to specify multiple where clauses delimited by a comma:

func itemsMatch<C1: SomeProtocol, C2: SomeProtocol where C1.ItemType == C2.ItemType,    C1.ItemType: SomeOtherProtocol>(foo: C1, bar: C2) -> Bool { return true }

Tags:

Swift