Hi guys, I've been stuck at this point for a while and I don't know if it's because of an unpacking limitation or that I'm doing something wrong.
To start with I have a Template which is a protocol that has an associated type which is a View.
I am having a complication with the existential types at the time of doing the unpacking when the type is inside a SwiftUI Binding with the structure that I have explained, here the code.
@Binding var input: any InputTemplate
var body: some View {
self.SomeInputBar(self.$input)
}
private func SomeInputBar<T: InputTemplate>(_ input: Binding<T>) -> AnyView {
AnyView(
T.InputBar(
input: input
)
)
}
The compiler gives me the following error
Type 'any InputTemplate' cannot conform to 'InputTemplate'
I have fixed it as follows but I don't like the solution at all
I believe that binding generic types doesn't work. For example, it should be relatively clear why this won't work:
func sum<T: AdditiveArithmetic>(arr: Array<T>) -> T {
return arr.reduce(into: T.zero, +=)
}
let myArray: Array<any AdditiveArithmetic> = [(1 as Int), (2.0 as Double)]
_ = sum(arr: myArray) // What is T? It can't be Int nor Double
Currently, the type system has no way to encode whether it's possible to do the Foo<any Bar> -> Foo<some Bar> transformation, so the compiler conservatively assumes that it never is.
Would it be possible to make the view itself generic over the input type?
struct EnclosingView<T: InputTemplate>: View {
@Binding var input: T
var body: some View {
someInputBar($input)
}
private func someInputBar(_ input: Binding<T>) -> AnyView {
// ...
}
}
But the example you have given just moves the problem up, at some point I have to convert the any into some somewhere and it has to be inside a Binding.
It really comes from an array, so it can't be opaque, it has to be an existential type and somewhere have to be the unboxing.