Подписание Google выполняется автоматически, также сразу после выхода.Свифт 4 - PullRequest
0 голосов
/ 07 декабря 2018

После написания логина по почте, я интегрирую социальные логины в свое приложение и начинаю с входа в Google.Теперь он запускается автоматически при запуске приложения, а не при нажатии кнопки входа в Google.Если я отменяю его во всплывающем окне, он бросает Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value в строку токена в AppDelegate`.Кроме того, выход из системы не мешает автоматически войти снова.Это было довольно запутанно, следуя инструкции из руководства Firebase для входа в Google, поэтому я уверен, что допустил некоторую очевидную ошибку.

Вот код на данный момент:

AppDelegate:

// start google sign in methods
    @available(iOS 9.0, *)
    func application(_ application: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any])
        -> Bool {
            return GIDSignIn.sharedInstance().handle(url,
                                                     sourceApplication:options[UIApplicationOpenURLOptionsKey.sourceApplication] as? String,
                                                     annotation: options[UIApplicationOpenURLOptionsKey.annotation])

    }

    func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?) {
        // ...
        print("User successfully signed in with Google",user)
        guard let idToken = user.authentication.idToken else {



            return

        }
        guard let accessToken = user.authentication.accessToken else {return}
        let credentials = GoogleAuthProvider.credential(withIDToken: idToken, accessToken: accessToken)

        Auth.auth().signInAndRetrieveData(with: credentials) { (user, error) in
            if let error = error {
                print("Failed to create user with Google account", error)
                return
            }

            print("Succesfully created new user in Firebase with Google account")
        }
        if let error = error {
            // ...
            print("User failed to sign in with Google", error)

            return
        }

        guard let authentication = user.authentication else { return }
        let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken,
                                                       accessToken: authentication.accessToken)

//        let storyboard = UIStoryboard(name: "Main", bundle: nil)
//        var mainVC = self.window?.visibleViewController as? MainNavigationController
//        mainVC = storyboard.instantiateViewController(withIdentifier: "MainNavigationController") as? MainNavigationController
    }

    func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!, withError error: Error!) {
        // Perform any operations when the user disconnects from app here.
        // ...
    }

    // end of google sign in 

Вход в Google должен выполнить переход к главному меню, но это не так.Только при первом входе он попадает в нужный vc.

Вот класс входа:

import UIKit
import Firebase
import GoogleSignIn



class LoginViewController: UIViewController, GIDSignInUIDelegate {
// outlets
    @IBOutlet weak var backGroundImage: UIImageView!

    @IBOutlet weak var userNameTextField: UITextField!

    @IBOutlet weak var emailTextField: UITextField!

    @IBOutlet weak var passwordTextField: UITextField!

    @IBOutlet weak var confirmPasswordTextField: UITextField!


    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        if Auth.auth().currentUser != nil {
            self.performSegue(withIdentifier: "skipSegue", sender: nil)
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        setGoogleButton()
        setFacebookButton()

    }

    // dismiss keyboard on touch outside textfields
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for txt in self.view.subviews {
            if txt.isKind(of: UITextField.self) && txt.isFirstResponder {
                txt.resignFirstResponder()
            }
        }
    }

    private func setGoogleButton() {
        GIDSignIn.sharedInstance().uiDelegate = self
        GIDSignIn.sharedInstance().signIn()
    }
    private func setFacebookButton() {

    }



    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

// Actions

    @IBAction func newUserRegisterButton(_ sender: Any) {

        if passwordTextField.text != confirmPasswordTextField.text{
            let alertController = UIAlertController(title: "Password Incorrect", message: "Please re-type password", preferredStyle: .alert)
            let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)

            alertController.addAction(defaultAction)
            self.present(alertController, animated: true, completion: nil)
        }
        else{
            Auth.auth().createUser(withEmail: emailTextField.text!, password: passwordTextField.text!){ (user, error) in
                if error == nil {
                    self.performSegue(withIdentifier: "skipSegue", sender: self)
                }
                else{
                    let alertController = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: .alert)
                    let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)

                    alertController.addAction(defaultAction)
                    self.present(alertController, animated: true, completion: nil)
                }
            }
        }
    }

    @IBAction func mailLogin(_ sender: UIButton) {


        Auth.auth().signIn(withEmail: emailTextField.text!, password: passwordTextField.text!) { (user, error) in
            if error == nil{
                self.performSegue(withIdentifier: "skipSegue", sender: self)
            }
            else{
                let alertController = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: .alert)
                let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)

                alertController.addAction(defaultAction)
                self.present(alertController, animated: true, completion: nil)
            }
        }
    }

    @IBAction func facebookLogin(_ sender: UIButton) {
    }

    @IBOutlet weak var signInButton: GIDSignInButton!
    @IBAction func googleSignInButton(_ sender: GIDSignInButton) {
        performSegue(withIdentifier: "skipSegue", sender: self)

    }


    @IBAction func logoutButton(_ sender: UIButton) {
    }

    @IBAction func skipButton(_ sender: UIButton) {

        performSegue(withIdentifier: "skipSegue", sender: self)
    }

}

Выход:

 @IBAction func logOutButton(_ sender: UIButton) {

        // firebase auth sign out
        let firebaseAuth = Auth.auth()
        do {
            try firebaseAuth.signOut()
        } catch let signOutError as NSError {
            print ("Error signing out: %@", signOutError)
        }

        // GSI log out
        GIDSignIn.sharedInstance().signOut()
        print("User successfully logged out Firebase with Google account")


        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let initial = storyboard.instantiateInitialViewController()
        UIApplication.shared.keyWindow?.rootViewController = initial




    }

    func signOutOverride() {
        do {
            GIDSignIn.sharedInstance().signOut()


            try GIDSignIn.sharedInstance()?.disconnect() 
            // Set the view to the login screen after signing out
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let initial = storyboard.instantiateInitialViewController()
            UIApplication.shared.keyWindow?.rootViewController = initial

//            let storyboard = UIStoryboard(name: "SignIn", bundle: nil)
//            let loginVC = storyboard.instantiateViewControllerWithIdentifier("SignInVC") as! SignInViewController
//            let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
//            appDelegate.window?.rootViewController = loginVC
        } catch let signOutError as NSError {
            print ("Error signing out: \(signOutError)")
        }
    }

Я прочитал много постов оаннулирование токенов и отключение пользователя от приложения, но они не могут реализовать эти решения, так как некоторые из них в obj-c, а другие в более старом быстром синтаксисе.У кого-то есть такая же проблема, как у меня?Спасибо, как обычно.

1 Ответ

0 голосов
/ 07 декабря 2018

После многих попыток и ошибок, благодаря саркастически полезной документации Google, я выяснил, в чем проблема.Они предлагают поставить знак внутри viewDidLoad()' and that obviously get's called every time the VC gets instantiated. I so Moved into the Google sign in button and left the delegate only in viewDidLoad () Теперь все работает как положено.

override func viewDidLoad() {
        super.viewDidLoad()
        GIDSignIn.sharedInstance().uiDelegate = self
        setFacebookButton()

    }


@IBOutlet weak var signInButton: GIDSignInButton!
    @IBAction func googleSignInButton(_ sender: GIDSignInButton) {
        GIDSignIn.sharedInstance()?.signIn()
        performSegue(withIdentifier: "skipSegue", sender: self)

    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...