Switch case to check ViewControllers conform to protocol

Fogmeister Source

I have a protocol...

protocol MyProtocol {}

And some of my view controllers conform to this protocol...

class MyViewController: UIViewController, MyProtocol {}

And some of them don't...

class OtherViewController: UIViewController {}

Now... I have a function which takes two UIViewController types. Depending on what types they are I need to do different things.

So I have a switch. In that switch I sometimes need to check the specific types and sometimes I need to check the protocol conformance.

switch (firstVC, secondVC) {
case is (MyViewController, OtherViewController):
    // do something this works
case is (OtherViewController, MyViewController):
    // do something else this works
case is (MyProtocol, MyProtocol):
    // this breaks...

The error that I get is...

Cast from (UIViewController, UIViewController) to unrelated type (MyProtocol, MyProtocol) always fails

But I know that not to be the case.

How can I check for the conformance of the UIViewControllers to my protocol?




answered 6 months ago Andreas Oetjen #1

The reson for the error is that you cannot cast a tuple to anything, especially not member-wise.

You could use case-let:

switch (firstVC, secondVC) {
    case (let mvc as MyViewController, let ovc as OtherViewController):
        // do something with mvc and ovc
    case (let ovc as OtherViewController, let mvc as MyViewController):
        // do something else
    case (let m1 as MyProtocol, let m2 as MyProtocol):
        // this breaks...

answered 6 months ago Fogmeister #2

As per @MartinR comment.

I can use...

case let (_ as MyProtocol, _ as MyProtocol):

Could've sworn I had tried that before.

In fact I needed to do a bit more checking in my case and so I did this...

case let (a as MyProtocol, _ as MyProtocol) where !(a is MyViewController):

Or something along those lines anyway.

comments powered by Disqus