refactor: the way providers are initialized. AnyView is used to render provider buttons.#1249
Conversation
|
I think we should just make the button views |
| associatedtype ButtonType: View | ||
| @MainActor var authButton: ButtonType { get } | ||
| var id: String { get } | ||
| @MainActor func authButton() -> AnyView |
There was a problem hiding this comment.
Did you try returning some View? You might need to annotate the function with @ViewBuilder
There was a problem hiding this comment.
cannot have some View as return type on protocol apparently. Get Xcode compiler error: 'some' type cannot be the return type of a protocol requirement; did you mean to add an associated type?
There was a problem hiding this comment.
I put together something that might help: https://gist.github.com/peterfriese/d9745f366fb4f857daf077e93b1eb01f
import SwiftUI
protocol AuthProvider: Identifiable {
var id: String { get }
associatedtype ButtonType: View
var authButtonView: Self.ButtonType { get }
}
protocol FooProviderProtocol: AuthProvider {
func doFoo()
}
struct FooProviderImpl1: FooProviderProtocol {
var id: String = "FooProviderImpl1"
func doFoo() {
print("1")
}
var authButtonView: some View {
Text("1")
}
}
struct FooProviderImpl2: FooProviderProtocol {
var id: String = "FooProviderImpl2"
func doFoo() {
print("2")
}
var authButtonView: some View {
Text("2")
.background(Color.red)
}
}
protocol BarProviderProtocol: AuthProvider {
func doBar()
}
struct BarProviderImpl1: BarProviderProtocol {
var id: String = "BarProviderImpl1"
func doBar() {
print("1")
}
var authButtonView: some View {
Text("1")
}
}
struct BarProviderImpl2: BarProviderProtocol {
var id: String = "BarProviderImpl2"
func doBar() {
print("2")
}
var authButtonView: some View {
Text("2")
.background(Color.red)
}
}
struct ContentView<Provider: AuthProvider>: View {
var provider: Provider
var body: some View {
VStack {
provider.authButtonView
}
}
}
#Preview {
ContentView(provider: BarProviderImpl2())
}
morganchen12
left a comment
There was a problem hiding this comment.
Ok to use AnyView since there's no good way to get concrete view types from a module that may or may not be included. We can revisit this decision if it causes noticeable performance issues.
AnyView is used to render provider buttons.
I cannot find a way to make it work where the Buttons are not type erased.
We have types unknown to core auth package and we're trying to render unknown button types in core auth package. How can we render without using type erasure?
If there is a clever way of doing this, I would love to know.