-1

I want to declare a variable

var specialVC: UIViewController & MyProtocol.

And I have a function

func doStuff<T: UIViewController & MyProtocol> { ... }

However, when I try to pass in my variable into the doStuff, it says UIViewController doesn't conform to MyProtocol.

class MyClass: UIViewController {

    override func viewDidLoad() {
      super.viewDidLoad()
      var specialVC: UIViewController & MyProtocol
      doStuff(specialVC)
    }

    func doStuff<T: UIViewController & MyProtocol>(_ vc: T) {}

}

error: Argument type 'UIViewController' does not conform to expected type 'MyProtocol'

--- Update ---

After looking at Protocol doesn't conform to itself?, I am able to create an extension that specifies a class that conforms to a protocol. However, I won't be able to call doStuff() from this extension.

internal extension MyProtocol where Self: UIViewController {
     // call doStuff(self) here somehow?
}
Mocha
  • 2,035
  • 12
  • 29
  • Looks like another variant of [Protocol doesn't conform to itself?](https://stackoverflow.com/q/33112559/1187415) – Martin R Sep 13 '19 at 19:24
  • Hmm.. I could create an extension for that type, but I won't be able to access instance method doStuff. Thoughts I could achieve this? @MartinR – Mocha Sep 13 '19 at 19:38
  • What are you really trying to do? In particular, why do you think `doStuff` needs to be _generic_? – matt Sep 13 '19 at 20:10
  • doStuff will accept many types of viewControllers... AVC, BVC that all conform to MyProtocol. @Matt – Mocha Sep 13 '19 at 20:11
  • That is not a reason for using a _generic_. UIViewController is a type. It embraces all its subclasses. MyProtocol is a type. It embraces all its adopters. Why is this not just a function that takes an ordinary typed parameter? I ask you again, where is the need for _generic_? – matt Sep 13 '19 at 20:13
  • I may be confused about generics.. but how else can I pass in parameters of AVC and BVC into the same function that conform to MyProtocol? – Mocha Sep 13 '19 at 20:14
  • Well `MyClass` does not conform to `MyProtocol`, that's what the error says. – Pavel Zdenek Sep 13 '19 at 20:18

1 Answers1

2

There is nothing about your function that needs to be a generic. Just use the normal types-and-supertypes mechanism (polymorphism, inheritance, whatever you like to call it). Just type your parameter as the supertype; this tells the compiler that it inherits all features of the supertype.

protocol MyProtocol : UIViewController { // Swift 5 syntax
    var thingy : String { get set }
}
class MyViewController : UIViewController, MyProtocol {
    var thingy = "howdy"
}
func doStuff(_ vc: MyProtocol) {
    print(vc.title) // legal, because we know it's a view controller
    print(vc.thingy) // legal, because we know it's a MyProtocol
}
matt
  • 515,959
  • 87
  • 875
  • 1,141