Classe em conformidade com o protocolo como parâmetro de function no Swift

Em Objective-C, é possível especificar uma class em conformidade com um protocolo como um parâmetro de método. Por exemplo, eu poderia ter um método que permita somente um UIViewController que esteja de acordo com o UITableViewDataSource :

 - (void)foo:(UIViewController *)vc; 

Não consigo encontrar uma maneira de fazer isso no Swift (talvez ainda não seja possível). Você pode especificar vários protocolos usando func foo(obj: protocol) , mas como você exige que o object também seja de uma determinada class?

Você pode definir foo como uma function genérica e usar restrições de tipo para exigir uma class e um protocolo.

Swift 4

 func foo(vc: T) { ..... } 

Swift 3 (também funciona para o Swift 4)

 func foo(vc:T) where T:UITableViewDataSource { .... } 

Swift 2

 func foo(vc: T) { // access UIViewController property let view = vc.view // call UITableViewDataSource method let sections = vc.numberOfSectionsInTableView?(tableView) } 

A documentação do livro Swift sugere que você use restrições de tipo com uma cláusula where:

 func someFunction(inParam: C1) {} 

Isso garante que “inParam” é do tipo “SomeClass” com uma condição que também adere ao “SomeProtocol”. Você ainda tem o poder de especificar várias cláusulas where delimitadas por uma vírgula:

 func itemsMatch(foo: C1, bar: C2) -> Bool { return true } 

No Swift 4 você pode conseguir isso com o novo & assinar:

 let vc: UIViewController & UITableViewDataSource 

Com o Swift 3, você pode fazer o seguinte:

 func foo(_ dataSource: UITableViewDataSource) { self.tableView.dataSource = dataSource } func foo(_ delegateAndDataSource: UITableViewDelegate & UITableViewDataSource) { //Whatever } 

Nota em setembro de 2015 : Esta foi uma observação nos primeiros dias do Swift.

Parece ser impossível. A Apple também tem esse aborrecimento em algumas de suas APIs. Aqui está um exemplo de uma class recém-introduzida no iOS 8 (a partir do beta 5):

UIInputViewController textDocumentProxy :

Definido no Objective-C da seguinte forma:

 @property(nonatomic, readonly) NSObject *textDocumentProxy; 

e em Swift:

 var textDocumentProxy: NSObject! { get } 

Link para a documentação da Apple: https://developer.apple.com/library/prerelease/iOS/documentation/UIKit/Reference/UIInputViewController_Class/index.html#//apple_ref/occ/instp/UIInputViewController/textDocumentProxy

E quanto a este caminho ?:

 protocol MyProtocol { func getTableViewDataSource() -> UITableViewDataSource func getViewController() -> UIViewController } class MyVC : UIViewController, UITableViewDataSource, MyProtocol { // ... func getTableViewDataSource() -> UITableViewDataSource { return self } func getViewController() -> UIViewController { return self } } func foo(_ vc:MyProtocol) { vc.getTableViewDataSource() // working with UITableViewDataSource stuff vc.getViewController() // working with UIViewController stuff }