google / google/GoogleSignIn-iOS

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

オープン
#49 コメント 5 件 リアクション 7 件 担当者 0 名 GitHub で見る
主要言語
Objective-C
スター
750
フォーク
282
平均マージ
2日 15時間
マージ済み PR(30日)
9

説明

## 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.

コントリビューションガイド

コントリビューションガイドを開く

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。