0

I'm trying to achieve type constraint on protocols. In my current project I have a following base controller. I examined this answer too but I don't understand why it isn't working.

class BaseViewController: UIViewController {
}

I declared two protocol based on my requirements.

protocol A: AnyObject {
    func execute()
}

extension A {
    func execute() {
        print("Execute")
    }
}

protocol B {
    func confirm()
}

extension B where Self: BaseViewController & A {
    func confirm() {
        
    }
}

What I'm trying to achieve is to prevent all classes which doesn't conform protocol A and BaseViewController also can't conform protocol B also.

However, when I try to conform protocol B in another UIViewController which doesn't conform protocol A there is no error.

class AnotherVC: UIViewController {
}

extension AnotherVC: B {
    func confirm() {
    }
}

How can I restrict other view controllers to conform protocol B if they don't conform protocol A and inherit from BaseViewController

atalayasa
  • 3,310
  • 25
  • 42
  • 1
    it’s working because AnotheVC is still a subclass of UIViewController, and BaseViewController is also subclass of UIViewController. So, basically BaseViewController have a IS-A relationship to UIViewController. – Tushar Sharma May 28 '21 at 09:38
  • I see your point but it needs to be also conform A protocol because of & ? @TusharSharma – atalayasa May 28 '21 at 11:25
  • 1
    protocol A have IS-A relationship with AnyObject. So, it basically means any class type can implement that protocol (reference types). When you say `extension AnotherVC: B` and B has a constraint that `self` should be `UIViewController & Class`. Which is exactly what you have, `AnotherVC` is a class and also subclass of UIViewController. – Tushar Sharma May 28 '21 at 11:44
  • Yes, you are right now I understand. When I constraint Self: BaseViewController & A I supposed to `AnotherVC` must conform to protocol B. Is there any way to achieve what I need? @TusharSharma – atalayasa May 28 '21 at 12:16

1 Answers1

0

I am not sure if below code is what you need, do let me know if that’s what you were looking for, else I will be happy to remove my answer.

protocol A:BaseViewController  {
    func execute()
}

protocol B:A {
    func confirm()
}

class BaseViewController: UIViewController {
    
}

class AnotherVC: B {
   
}

In above code compiler will give error saying-:

'A' requires that 'AnotherVC' inherit from ‘BaseViewController'

Once you inherit AnotherVC from BaseViewController, it will give another error saying-:

Type 'AnotherVC' does not conform to protocol ‘A'

Once you confirm the implementations errors will be resolved-:

class AnotherVC:BaseViewController, B {
    func confirm() {
        
    }
    
    func execute() {
        
    }
    
}
Tushar Sharma
  • 2,839
  • 1
  • 16
  • 38
  • Thanks for you effort and comment, but what I'd like to achieve is that for example I have two protocol A and B. I need to create a rule that if a class doesn't conform protocol A also can't conform protocol B. – atalayasa May 28 '21 at 13:21
  • @atalayasa I guess that’s what code does, when I implement AnotherVC with B, compiler complains that AnotherVC does not confirm BaseViewController and protocol A. Once we provide both rules only then it works. Or is it something else I missed. – Tushar Sharma May 28 '21 at 13:25
  • You are absolutely right, I thought so complicated now it's working as I wished :) – atalayasa May 28 '21 at 14:19