ios - 使用 SwiftUI 添加谷歌登录

标签 ios swift uikit google-signin swiftui

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

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

我在 uikit View Controller 中添加按钮,因为我想不出另一种方法来处理 Google 委托(delegate)

这是预览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

最佳答案

这是我使用任何按钮实现 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 and Facebook custom buttons

关于ios - 使用 SwiftUI 添加谷歌登录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57924768/

相关文章:

ios - 模块 'Fabric' 没有名为 'with' 的成员

ios - 如何在 swift 3.0 中拖动和缩放 UIView 内的 UIImageView ?

ios - Swift - 加载另一个单元格后更新单元格中的标签?

iOS 13 动画 View 不改变框架

ios - 为什么 touchesForView : returns only 1 touch?

ios - 更改 nsdictionary 中的 bool 值时的 EXC_BAD_ACCESS

iphone - UILabel 字体 : bold and italic

ios - 使用 ContactsUI 快速获取所有联系电话号码

ios - UISearchBar 按钮

ios - 如何呈现 View 及其 subview 的交集?