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 protocol associated types and inheritance contraints
Create a DataSource protocol with an associated type for your layout type:
protocol ColumnDataSourceProtocol: UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
associatedtype Layout: UICollectionViewFlowLayout
}
Make your DataSource base class conform to this protocol. You may need to add a typealias
to specify the associatedtype if the compiler cannot infer it:
class ColumnDataSource<FlowLayoutType: UICollectionViewFlowLayout>: NSObject, ColumnDataSourceProtocol {
typealias Layout = FlowLayoutType
// the rest stays the same
}
Adapt ColumnFlowLayoutable
to associate the data source type instead of the layout type. Constraining it to the ColumnDataSourceProtocol
lets you access its associated Layout
type:
protocol ColumnFlowLayoutable {
associatedtype DataSource: ColumnDataSourceProtocol
var columnDataSource: DataSource { get }
var customFlowLayout: DataSource.Layout { get }
}
Now you can subclass ColumnDataSource
:
class DataSource: ColumnDataSource<CustomFlowLayout> { /* ... */ }
returning swift protocol associated type in multiple methods
The solution you came up with by playing around is exactly what you need
As mentioned elsewhere, the main issue with your first protocol is that you're enforcing createSomeView()
createAnotherView()
both return the same type. While ViewA()
and ViewB()
are both candidates for V
, since they conform to View
they are still different types, and therefore cannot BOTH be V
in a given object.
By defining both V1
and V2
, you allow for each function to return a different type, or the same type, it's all acceptable. By making both V1
and V2
require View
conformance, you allow for the some View
syntax
Related Topics
Get Compiler Error in Swift Indexof()
Value of Type 'Tags' Has No Member 'Lastused'
Why Can't I Use Subscripting on a Ckrecord Object in Swift
Swift Error Using Initialized Properties in Expressions Before Super.Init
How to Return a Value from a Void Closure in Swift
Initializing Property via Closure
Hittest Prints Ar Entity Name Even When I am Not Tapping on It
Calculate the Number of Dimensions of a Multi-Dimensional Array in Swift
Count the Number of Lines in a Swift String
Why Use Float(Arc4Random())/0Xffffffff Instead of Drand()
Perform Migration by Adding List() and Another Model Class
Making a Http Post Request in Swift 2
Code Highlighting in Latex for Swift
Swiftui: Localizedstringkey with Indices
How to Detect the 2D Images Using Arkit and Realitykit
How to Compare Result to .Succeed in Swift
"Message from Debugger: Unable to Attach" When Running Tests on Osx App