Clase conforme al protocolo como parámetro de función en Swift

En Objective-C, es posible especificar una clase que se ajuste a un protocolo como un parámetro de método. Por ejemplo, podría tener un método que solo permita un UIViewController que se ajuste a UITableViewDataSource :

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

No puedo encontrar una manera de hacer esto en Swift (quizás aún no sea posible). Puede especificar múltiples protocolos usando func foo(obj: protocol) , pero ¿cómo requiere que el objeto sea también de una clase en particular?

Puede definir foo como una función genérica y usar restricciones de tipo para requerir una clase y un protocolo.

Swift 4

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

Swift 3 (funciona también para 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) } 

La documentación del libro Swift sugiere que use restricciones de tipo con una cláusula where:

 func someFunction(inParam: C1) {} 

Esto garantiza que “inParam” es del tipo “SomeClass” con la condición de que también se adhiera a “SomeProtocol”. Incluso tiene el poder de especificar múltiples cláusulas where delimitadas por una coma:

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

En Swift 4 puedes lograr esto con el nuevo & sign:

 let vc: UIViewController & UITableViewDataSource 

Con Swift 3, puede hacer lo siguiente:

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

Nota en septiembre de 2015 : Esta fue una observación en los primeros días de Swift.

Parece ser imposible. Apple también tiene esta molestia en algunas de sus API. Aquí hay un ejemplo de una clase recientemente introducida en iOS 8 (a partir de beta 5):

UIInputViewController de textDocumentProxy :

Definido en Objective-C de la siguiente manera:

 @property(nonatomic, readonly) NSObject *textDocumentProxy; 

y en Swift:

 var textDocumentProxy: NSObject! { get } 

Enlace a la documentación de Apple: https://developer.apple.com/library/prerelease/iOS/documentation/UIKit/Reference/UIInputViewController_Class/index.html#//apple_ref/occ/instp/UIInputViewController/textDocumentProxy

¿Qué hay de esta manera ?:

 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 }