Skip to content

example of ViewBuilder issue #1250

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

Closed
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
import SwiftUI

public protocol ExternalAuthProvider {
var id: String { get }
var id: String { get }
associatedtype ButtonType: View
@MainActor @ViewBuilder func authButtonView() -> ButtonType
@MainActor func authButton() -> AnyView
}

Expand Down Expand Up @@ -65,15 +67,9 @@ private final class AuthListenerManager {
@MainActor
@Observable
public final class AuthService {
public init(configuration: AuthConfiguration = AuthConfiguration(), auth: Auth = Auth.auth(),
googleProvider: (any GoogleProviderProtocol)? = nil,
facebookProvider: (any FacebookProviderProtocol)? = nil,
phoneAuthProvider: (any PhoneAuthProviderProtocol)? = nil) {
public init(configuration: AuthConfiguration = AuthConfiguration(), auth: Auth = Auth.auth()) {
self.auth = auth
self.configuration = configuration
self.googleProvider = googleProvider
self.facebookProvider = facebookProvider
self.phoneAuthProvider = phoneAuthProvider
string = StringUtils(bundle: configuration.customStringsBundle ?? Bundle.module)
listenerManager = AuthListenerManager(auth: auth, authEnvironment: self)
}
Expand All @@ -96,8 +92,8 @@ public final class AuthService {
private var listenerManager: AuthListenerManager?
private var signedInCredential: AuthCredential?

private var providers: [ExternalAuthProvider] = []
public func register(provider: ExternalAuthProvider) {
private var providers: [any ExternalAuthProvider] = []
public func register(provider: any ExternalAuthProvider) {
providers.append(provider)
}

Expand All @@ -111,6 +107,25 @@ public final class AuthService {
)
}

@ViewBuilder
public var googleButton: some View {
if googleProvider != nil {
// For purpose of demonstration
// This produces "Type 'any View' cannot conform to 'View'"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@peterfriese - the problem is when we try to render from core package, Xcode produces this compiler error. I don't know how to get around it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you take a look at https://gist.github.com/peterfriese/d9745f366fb4f857daf077e93b1eb01f and see if this approach helps?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@peterfriese - here is the commit attempting to follow your example: 8c38462 (#1250)

googleProvider!.authButtonView()
} else {
EmptyView()
}
}

// public func renderButtonViews(spacing: CGFloat = 16) -> some View {
// VStack(spacing: spacing) {
// ForEach(providers, id: \.id) { provider in
// provider.authButtonView()
// }
// }
// }

private var safeGoogleProvider: any GoogleProviderProtocol {
get throws {
guard let provider = googleProvider else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ extension AuthPickerView: View {
Text(authService.authenticationFlow == .login ? "Login" : "Sign up")
VStack { Divider() }
EmailAuthView()
authService.renderButtons()

VStack { Divider() }
HStack {
Text(authService
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,15 @@ public class FacebookProviderSwift: FacebookProviderProtocol {
rawNonce = CommonUtils.randomNonce()
shaNonce = CommonUtils.sha256Hash(of: rawNonce)
}

@MainActor public func authButton() -> AnyView {
AnyView(SignInWithFacebookButton())
}

@MainActor @ViewBuilder public func authButtonView() -> some View {
SignInWithFacebookButton()
}

@MainActor public func signInWithFacebook(isLimitedLogin: Bool) async throws -> AuthCredential {
let trackingStatus = ATTrackingManager.trackingAuthorizationStatus
let tracking: LoginTracking = trackingStatus != .authorized ? .limited :
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ public class GoogleProviderSwift: @preconcurrency GoogleProviderProtocol {
})
}

@MainActor @ViewBuilder public func authButtonView() -> some View {
GoogleSignInButton {
Task {
try await self.signInWithGoogle(clientID: self.clientID)
}
}
}

@MainActor public func signInWithGoogle(clientID: String) async throws -> AuthCredential {
guard let presentingViewController = await (UIApplication.shared.connectedScenes
.first as? UIWindowScene)?.windows.first?.rootViewController else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ public typealias VerificationID = String
public class PhoneAuthProviderSwift: @preconcurrency PhoneAuthProviderProtocol {
public let id: String = "phone"
public init() {}

@MainActor public func authButton() -> AnyView {
AnyView(Text("phone button TODO"))
}

@MainActor @ViewBuilder public func authButtonView() -> some View {
Text("phone button TODO")
}

@MainActor public func verifyPhoneNumber(phoneNumber: String) async throws -> VerificationID {
return try await withCheckedThrowingContinuation { continuation in
PhoneAuthProvider.provider()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,9 @@ struct ContentView: View {
shouldAutoUpgradeAnonymousUsers: true,
emailLinkSignInActionCodeSettings: actionCodeSettings
)
let facebookProvider = FacebookProviderSwift()
let phoneAuthProvider = PhoneAuthProviderSwift()

authService = AuthService(
configuration: configuration,
facebookProvider: facebookProvider,
phoneAuthProvider: phoneAuthProvider
configuration: configuration
)
// Transition to this api
.withGoogleSignIn()
Expand Down
Loading