Swift Protocol Inheritance and Protocol Conformance Issue

Swift Protocol inheritance and protocol conformance issue

You cannot implement a read-write property requirement of type BasePresenterProtocol? with a property of type DashboardPresenterProtocol?.

Consider what would happen if this were possible, and you upcast an instance of DashboardPresenter to DashboardViewProtocol. You would be able to assign anything that conforms to BasePresenterProtocol to a property of type DashboardPresenterProtocol? – which would be illegal.

For this reason, a read-write property requirement has to be invariant (although it's worth noting that a readable-only property requirement should be able to be covariant – but this currently isn't supported).

Difference when declaring swift protocol using inheritance from another protocol or using where Self

Speaking about Swift5, there is no difference between the two forms, see Swift 5 Release notes:

Protocols can now constrain their conforming types to those that subclass a given class. Two equivalent forms are supported:

protocol MyView: UIView { /*...*/ }
protocol MyView where Self: UIView { /*...*/ }

Swift 4.2 accepted the second form, but it wasn’t fully implemented and could sometimes crash at compile time or runtime. (SR-5581) (38077232)

A protocol is not conforming to a class inherited from a generic parent class?

Because you are doing this in a static function, you can't use self to refer to an instance of your VC. Instead, you have an instance of your VC already! It's vc.

Just set vc as the delegate instead of self:

adapter.delegate = vc

Protocol inheritance with associated type

Once a protocol has an associated type, that protocol can't be used as a type by itself for instance declarations-- only for generic constraints and declaring conformance.

So in this case, Swift is saying "yeah, but what is the concrete type for StartRouterProtocol's associated type?"

In this case, it's asking you to either:

  1. Use a concrete type directly, i.e. let router: MyStartViewClass with this conformance declaration, elsewhere: class MyStartViewClass: StartRouterProtocol { ... })
  2. OR, push the need for a concrete type up one layer, as a generic constraint i.e.
class MyRouterController<T: StartRouterProtocol> {
let router: T
}

This is probably not what you were hoping for, but unfortunately associated types add complexity to how you use protocols, especially if you're familiar with generics & interfaces from other languages. (i.e. Java/C# interfaces)

You can work around some aspects of associated types by using a concept called "type erasure" -- but that can cause other problems and complexity.

Here's some further reading that may help: https://medium.com/monstar-lab-bangladesh-engineering/swift-from-protocol-to-associatedtype-then-type-erasure-a4093f6a2d08

Swift 2 add protocol conformance to protocols

As the error message says: an extension of a protocol cannot have an inheritance clause. Instead, you could make MyData protocol inherit from Equatable in the original declaration.

protocol MyData: Equatable {
var myDataID: Int { get }
}

You could then extend add an implementation of == for types that conform to MyData:

func == <T: MyData>(lhs: T, rhs: T) -> Bool {
return lhs.myDataID == rhs.myDataID
}

However, I would highly not recommend this! If you add more properties to conforming types, their properties won't be checked for equality. Take the example below:

struct SomeData: MyData {
var myDataID: Int
var myOtherData: String
}

let b1 = SomeData(myDataID: 1, myOtherData: "String1")
let b2 = SomeData(myDataID: 1, myOtherData: "String2")

b1 == b2 // true, although `myOtherData` properties aren't equal.

In the case above you'd need to override == for SomeData for the correct result, thus making the == that accepts MyData redundant.



Related Topics



Leave a reply



Submit