ios - 使用 SwiftUI 添加谷歌登录
问题描述
我正在尝试使用带有 UIKitViewController 的 swiftUI 添加 google 登录,由于某种原因,我很难显示按钮没有出现在样式中
登录和按钮工作完美,但在某些时候按钮的样式停止出现
我在 uikit 视图控制器中添加按钮,因为我想不出另一种方法来处理 Google 委托
//
// 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,就不必使用您提供给我们的默认按钮了。
推荐阅读
- python - 在python中将日期(月、日、年、时间)转换为日期时间格式
- spring - 为什么@RestController 默认使用单例范围?
- powershell - 如何使用 Powershell 脚本在远程计算机上查找 PST 文件
- php - 数据表页面就像只有一页一样工作
- angular - 单击铅笔图标编辑内容
- javascript - JavaScript 对象语法和符号
- json - 从 Bigquery 中的 json 获取数组
- javascript - React Native 和 Apollo 客户端
- javascript - 单击 highcharts 中的图例时,柱形图未重置
- unity3d - 如何在我的 3d FPS 游戏中让手跟随相机?