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:
- Use a concrete type directly, i.e.
let router: MyStartViewClass
with this conformance declaration, elsewhere:class MyStartViewClass: StartRouterProtocol { ... }
) - 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
How to Load Url in Uiwebview in Swift
Swiftui View and @Fetchrequest Predicate With Variable That Can Change
Sharing Userdefaults Between Extensions
Swift Compiler Segmentation Fault When Building
How to Do a Swift For-In Loop With a Step
Uitextview With Hyperlink Text
Property Initializers Run Before 'Self' Is Available
Fix Warning "C-Style For Statement Is Deprecated" in Swift 3
Usb Connection Delegate on Swift
Is This Response from the Compiler Valid
How to Pass Multiple Enum Values as a Function Parameter
Weak References in Swift Playground Don't Work as Expected
In Swiftui, How to Increase the Height of a Button
How to Append Elements into a Dictionary in Swift
Protocol Doesn't Conform to Itself