The following hierarchy of protocols is available as an illustration:
And here is a concrete implementation of bottom protocols on illustration:
// MARK: -
open class View<State: ViewStateProtocol, Configuration: ViewConfigurationProtocol>: UIView, ViewProtocol {
// ...
}
// MARK: -
public struct ViewState: ViewStateProtocol {
public var traitCollection: UITraitCollection
public var isShimmering = false
public init(traitCollection: UITraitCollection) {
self.traitCollection = traitCollection
}
}
// MARK: -
public struct ViewConfiguration: ViewConfigurationProtocol {
public init() {
}
}
The problem lies in this part of the code. The compiler gives an incomprehensible Cannot convert value of type 'ViewState' to specified type 'any ViewStateProtocol':
let state: any ViewStateProtocol = ViewState(traitCollection: .init()) // Okay
let configuration: any ViewConfigurationProtocol = ViewConfiguration() // Okay
let view = View<ViewState, ViewConfiguration>(frame: .zero)
let anyView: any ViewProtocol<any ViewStateProtocol, any ViewConfigurationProtocol> = view // Compile error
Is it something I'm doing wrong or?
xwu
(Xiaodi Wu)
2
I'm only looking at this really quickly, so I could be wrong, and you've omitted some information in "// ...," but filling in the blanks it seems:
View<ViewState, ViewConfiguration> means that View.State is the concrete type ViewState. I assume that View actually has a property of that type somewhere, as the name "state" implies.
any ViewProtocol<any ViewStateProtocol, any ViewConfigurationProtocol> means that instances are required to store state typed any ViewStateProtocol, an existential box.
- Your instance,
view, is of the first type; it cannot store an instance of any ViewStateProtocol as its State, because as we said, View.State is the concrete type View.State. Therefore, you have made an error.
1 Like
Updated
Thanks for the response!
I think I missed the main point and everything fell into place. any ViewProtocol<any ViewStateProtocol, any ViewConfigurationProtocol> mean any ViewProtocol where State == any ViewStateProtocol, Configuration == any ViewConfigurationProtocol and not that any ViewProtocol where State: ViewStateProtocol, Configuration: ViewConfigurationProtocol.
But how do I express the original limitation without creating such a protocol? From:
protocol ViewProtocol<State, Configuration>:
UIView, ViewItem, ViewConfigurable, ViewSetupable {
}
to the following:
protocol ViewProtocol<State, Configuration>:
UIView, ViewItem, ViewConfigurable, ViewSetupable
where State: ViewStateProtocol, Configuration: ViewConfigurationProtocol {
}