google / google/GoogleSignIn-iOS

Using v6 in SwiftUI: `.signIn()` workaround and suggestions for SwiftUI support

Đang mở
#49 5 bình luận 7 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
Objective-C
Star
750
Fork
282
Merge trung bình
2 ngày 15 giờ
Pull request đã merge (30 ngày)
9

Mô tả

## Background

With SwiftUI being the way forward for iOS dev, I would have hoped GoogleSignIn had better support for SwiftUI.

Unfortunatley there isn't any SwiftUI-focused documentation, and the patterns changed in v6 (e.g., no delegates) seem to make implementing GIDSignIn harder in SwifUI.

The biggest issue I've had (and clearest example) is below:

## Sign In

The main issue I've run into is with this function:
```swift
- (void)signInWithConfiguration:(GIDConfiguration *)configuration
presentingViewController:(UIViewController *)presentingViewController
callback:(nullable GIDSignInCallback)callback;
```

SwiftUI doesn't have view controllers, but we need to instantiate _a_ sign-in view from SwiftUI.

There's two workarounds:
1. Create a `UIViewRepresentable` view that accesses the root view controller with something like `UIApplication.shared.windows.last?.rootViewController`
1. Create a `UIViewRepresentable` view that instantiates a dummy `UIViewController` that then calls some `AuthManager` singleton, which in turn calls `sharedInstance.signIn(...)`.

This is so confusing to implement primarily because there _already existed_ a delegate pattern and a non-`presentingVC` parameter [before v6 of this library](https://developers.google.com/identity/sign-in/ios/quick-migration-guide).

Tying it all together would be something like this:

```swift
// AuthManager.swift

class AuthManager {

var shared = AuthManager()
var config = GIDConfiguration()

func signIn(withVC vc: UIViewController) {
GIDSignIn.signIn(with: config, presenting: vc) { /* ... */ }
}
}

// AuthWrapper.swift

class AuthVC: UIViewController {
func signIn() {
AuthManager.shared.signIn(withVC: self)
}
}

class AuthVCWrapper: UIViewRepresentable {
let authVC = AuthVC() // strong ref
func makeUIViewController() {
return authVC
}
func signIn() {
authVC.signIn() // single responsibility principle
}
}

// SignIn.swift

class SignIn: View {
var authWrapper = AuthVCWrapper()

var body: some View {
ZStack {
authWrapper
Button(action: authWrapper.signIn()) {
Text("Sign In")
}
}
}
}
```

To me personally this seems verbose.

## Delegates

In addition, the delegate pattern [seems to have been removed](https://developers.google.com/identity/sign-in/ios/quick-migration-guide). This would have made it much easier to work alongside a more detached MVVM pattern instead of routing everything through the `sharedInstance` singleton anyways.

Is there a reason for why the delegate pattern was removed?

## Suggestions

Given that `SFSafariViewController` is a UIKit component, having `GIDSignIn` instantiate the `UIViewControllerRepresentable` and alongisde an overloaded `sharedInstance.signIn()` for SwiftUI users would vastly shorten the above example.

The other suggestion I have is maybe a timeline on SwiftUI support, or some documentation on existing workarounds, as most blog posts are written pre-v6, and instruct users to create delegates and such, which is no longer supported.

## Final Thoughts

I guess this brings me to my final question: is there SwiftUI support planned at all?

I'd be happy to write a sample project to catch up the Objective-C one currently in this repo, but without any official documentation for SwiftUI support it'd need a good chunk of review.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.