首页 > 解决方案 > 使用 SwiftUI 添加谷歌登录

问题描述

我正在尝试使用带有 UIKitViewController 的 swiftUI 添加 google 登录,由于某种原因,我很难显示按钮没有出现在样式中

登录和按钮工作完美,但在某些时候按钮的样式停止出现

我在 uikit 视图控制器中添加按钮,因为我想不出另一种方法来处理 Google 委托

这是预览https://ibb.co/tYhx62b

//
//  GoogleSignInButtonView.swift
//
//  Created by Ivan Schaab on 11/09/2019.
//  Copyright © 2019 Ivan Schaab. All rights reserved.
//
import GoogleSignIn
import SwiftUI

struct GoogleSignInButtonView: View {

    @EnvironmentObject var lvm: LoginViewModel

    var body: some View {
        HStack {
            Spacer()
            GoogleButtonViewControllerRepresentable { (token, user) in
                // Google Login Success
                // Now do Backend Validations
                self.lvm.loginOauth(token: token, user: user)
            }
            Spacer()
        }.frame(alignment: .center)
    }
}

class GoogleButtonUIKitViewController: UIViewController {

    var signInButton = GIDSignInButton()

    override func viewDidLoad() {
        super.viewDidLoad()

        GIDSignIn.sharedInstance().clientID = Constants.GOOGLE_CLIENT_ID
        self.view.addSubview(signInButton)

        GIDSignIn.sharedInstance()?.presentingViewController = self

        // Automatically sign in the user.
        GIDSignIn.sharedInstance()?.restorePreviousSignIn()
    }
}

struct GoogleButtonViewControllerRepresentable: UIViewControllerRepresentable
{
    let vc = GoogleButtonUIKitViewController()
    var googleResponse: (String, User) -> Void

    func makeUIViewController(context: Context) -> GoogleButtonUIKitViewController {
        return vc
    }
    func updateUIViewController(_ uiViewController: GoogleButtonUIKitViewController, context: Context) {}
    func makeCoordinator() -> Coordinator {
        Coordinator(vc: vc, googleResponse: googleResponse)
    }

    static func dismantleUIViewController(_ uiViewController: GoogleButtonUIKitViewController, coordinator: GoogleButtonViewControllerRepresentable.Coordinator) {
        print("DISMANTLE")
    }

    class Coordinator: NSObject, GIDSignInDelegate  {
        var foo: (String, User) -> Void
        init(vc: GoogleButtonUIKitViewController, googleResponse: @escaping (String, User) -> Void) {
            self.foo = googleResponse
            super.init()
            GIDSignIn.sharedInstance()?.delegate = self
        }

        func sign(_ signIn: GIDSignIn!, didSignInFor googleUser: GIDGoogleUser!, withError error: Error!) {
            if let error = error {
                if (error as NSError).code == GIDSignInErrorCode.hasNoAuthInKeychain.rawValue {
                    print("The user has not signed in before or they have since signed out.")
                } else {
                    print("\(error.localizedDescription)")
                }
                return
            }
//            let userId = googleUser.userID                  // For client-side use only!
            let idToken = googleUser.authentication.idToken // Safe to send to the server
            let email = googleUser.profile.email

            if googleUser.profile.hasImage{
                let imageUrl = googleUser.profile.imageURL(withDimension: 120)
                print(" image url: ", imageUrl?.absoluteString ?? "NO URL")
            }

            let user : User = User(id: 1, name: googleUser.profile.givenName, surname: googleUser.profile.familyName, imgName: ""  , email: googleUser.profile.email)

            print("email: ",email ?? "NO EMAIL")

            foo(idToken! , user)
        }
    }
}



#if DEBUG
struct SomeRepView_Previews: PreviewProvider {
    static var previews: some View {
        GoogleSignInButtonView().environmentObject(LoginViewModel())
    }
}
#endif

标签: iosswiftuikitgoogle-signinswiftui

解决方案


这是我使用任何按钮实现 Facebook 和 Google 登录的代码的一部分,希望对您有所帮助

import SwiftUI
import GoogleSignIn
import FBSDKLoginKit

var body: some View {
    LoadingView(isShowing: .constant(loading)) {
        NavigationView {
            ScrollView {
                VStack {

                    Text("Or Login with").font(.footnote)

                    HStack {
                        Button(action: self.logginFb, label: {
                            Image("ic_facebook").foregroundColor(Color.white).frame(width: 20, height: 20)
                        })
                                .padding(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16))
                                .background(Color("facebook"))
                                .cornerRadius(8.0)

                        Button(action: self.socialLogin.attemptLoginGoogle, label: {
                            Image("ic_google").frame(width: 20, height: 20)
                        })
                                .padding(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16))
                                .background(Color.white)
                                .cornerRadius(8.0)
                                .shadow(radius: 4.0)


                    }.padding()
                }.padding(.all, 32)
            }.navigationBarTitle(Text("Login"))
        }
    }
}

    func logginFb() {
        socialLogin.attemptLoginFb(completion: { result, error in

        })
    }


struct SocialLogin: UIViewRepresentable {

    func makeUIView(context: UIViewRepresentableContext<SocialLogin>) -> UIView {
        return UIView()
    }

    func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<SocialLogin>) {
    }

    func attemptLoginGoogle() {
        GIDSignIn.sharedInstance()?.presentingViewController = UIApplication.shared.windows.last?.rootViewController
        GIDSignIn.sharedInstance()?.signIn()
    }

    func attemptLoginFb(completion: @escaping (_ result: FBSDKLoginManagerLoginResult?, _ error: Error?) -> Void) {
        let fbLoginManager: FBSDKLoginManager = FBSDKLoginManager()
        fbLoginManager.logOut()
        fbLoginManager.logIn(withReadPermissions: ["email"], from: UIApplication.shared.windows.last?.rootViewController) { (result, error) -> Void in
            completion(result, error)
        }
    }

}

struct LoginView_Previews: PreviewProvider {
    static var previews: some View {
        LoginView()
    }
}

AppDelegate 中 google 和 facebook 的配置与其文档相同。

现在有了 swiftUI,就不必使用您提供给我们的默认按钮了。

Google 和 Facebook 自定义按钮 Google 和 Facebook 自定义按钮


推荐阅读