Skip to content

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

Merged
merged 8 commits into from
May 9, 2025

Conversation

russellwheatley
Copy link
Member

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.

@morganchen12
Copy link
Contributor

I think we should just make the button views any View since they're small views that aren't nested and we can't pass type data for these particular views up from subdependencies to the root Auth module.

associatedtype ButtonType: View
@MainActor var authButton: ButtonType { get }
var id: String { get }
@MainActor func authButton() -> AnyView
Copy link
Contributor

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

Copy link
Member Author

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?

Copy link
Contributor

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())
}

Copy link
Member Author

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

Copy link
Contributor

@morganchen12 morganchen12 left a 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.

@russellwheatley russellwheatley changed the title question: how to make Views concrete? (i.e not use Any View) refactor: the way providers are initialized. AnyView is used to render provider buttons. May 9, 2025
@russellwheatley russellwheatley marked this pull request as ready for review May 9, 2025 08:45
@russellwheatley russellwheatley merged commit dfbfbee into main May 9, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants