-
Notifications
You must be signed in to change notification settings - Fork 485
refactor: the way providers are initialized. AnyView
is used to render provider buttons.
#1249
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you try returning some View
? You might need to annotate the function with @ViewBuilder
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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())
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've responded in the other PR: #1250
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.