Search code examples
iosswiftoverridingprotocols

override protocol extension default implementation


Consider following code

// GENERATED PROTOCOL, CANNOT BE MODIFIED
protocol SomeProtocol {
}

// GENERATED CLASS, CANNOT BE MODIFIED
class A {
}

// GENERATED CLASS, CANNOT BE MODIFIED
class B: A, SomeProtocol {
}



// I CAN CHANGE ONLY FROM HERE BELOW

extension SomeProtocol {
    func someMethod() {
        print("protocol implementation")
    }
}

extension B {
    func someMethod() {
        print("class implementation")
    }
}


let some: SomeProtocol = B()
some.someMethod() //this prints "protocol implementation"

I want some.someMethod() to print "class implementation". I know there are ways to achieve this, one would be to add in SomeProtocol someMethod, but, unfortunately, I cannot change none of SomeProtocol, A or B, these are generated. I can only play with extensions. Is there a way to achieve this without touching the 3 mentioned before?


Solution

  • If you declare the variable as the protocol type, it will always take the default implementation of the protocol method, since the method is declared in an extension of the protocol.

    Without adding the method to the protocol declaration itself (which you've stated to be not possible for you), the only way to access the specific implementation of your conforming type is to downcast some to B or store it as B in the first place.

    let some: SomeProtocol = B()
    some.someMethod() //this prints "protocol implementation"
    (some as? B)?.someMethod() // this prints "class implementation"
    
    let someB = B()
    someB.someMethod() // this prints "class implementation"