【问题标题】:Swift: I am unable to pass back a variable from Firebase FIRAuth function to a declared variable from a parent funcitonSwift:我无法将 Firebase FIRAuth 函数中的变量传递回父函数中声明的变量
【发布时间】:2016-11-12 14:58:31
【问题描述】:

我是 swift 的新手,我一直在努力学习自己。我遇到了一个问题,我不确定如何解决它。代码如下:

import Foundation
import Firebase

class UserLogin {

var email:String?
var password:String?

init(email:String, password:String){
    self.email = email
    self.password = password
}

func userLogin() -> String{
    var errorMsg:String = ""
    //Email & Password Integrity check
    if (email == ""){
        errorMsg = "Please enter your email"
    } else if (email?.rangeOfString("@") == nil || email?.rangeOfString(".") == nil){
        errorMsg = "Email is invalid"
    }else if (password == ""){
        errorMsg = "Please enter your password"
    }  else if (password?.characters.count < 8){
        errorMsg = "Password is invalid"
    }else{
        print("Logging In... with Email:\(email!) and Password:\(password!)")
        //Firebase Authentication Process"

        FIRAuth.auth()?.signInWithEmail(email!, password: password!){ (user, error) in
            // ...
            if (error != nil){
                let errorCode = error!.code
                if (errorCode == 17009){
                    errorMsg = "You have entered the wrong password"
                } else if (errorCode == 17011){
                    errorMsg = "Your email does not exist"
                } else if (errorCode == 17010) {
                    errorMsg = "You have tried to login too many times with the wrong credentials. Please try again later."
                } else {
                    print(error)
                }
            } else {
                print("User is Logged In")
                errorMsg = "You have successfully Logged In"
            }
        }
    }
    return errorMsg
}

}

基本上在我的 ViewController 中,我有一个像这样工作的单独代码

let alert = UIAlertController(title: "Error", message: errorMsg, preferredStyle: .Alert)
        let action = UIAlertAction(title: "OK", style: .Default, handler: nil)
        alert.addAction(action)
        self.presentViewController(alert, animated: true, completion: nil)

这适用于我的 userLogin func 中的所有 errorMsg,但对于基于 FIRAuth 提供的 error.code 生成的少数 errorMsg,它不会出现。

我阅读并认为这可能是因为 FIRAuth 是一个异步调用,但我不知道如何解决它。

很抱歉,如果这听起来很愚蠢,但我整天都在想办法但无济于事,如果能得到你们的帮助真是太棒了。

补充: 我按照建议实现了 CompletionHandler,但我不明白为什么它不起作用,尽管它应该......以下是我的代码。

UserLogin1.swift

import Foundation
import Firebase

class UserLogin1 {

var email:String?
var password:String?

init(email:String, password:String){

    self.email = email
    self.password = password
}

func userLogin(completion:(message:String)->()) {

    var errorMsg:String = ""
    //Email & Password Integrity check
    if (email == ""){

        errorMsg = "Please enter your email"

    } else if (email?.rangeOfString("@") == nil || email?.rangeOfString(".") == nil){

        errorMsg = "Email is invalid"

    }else if (password == ""){

        errorMsg = "Please enter your password"

    }  else if (password?.characters.count < 8){

        errorMsg = "Password is invalid"

    }else if (errorMsg != ""){

        completion(message: errorMsg)

    }else{

        print("Logging In... with Email:\(email!) and Password:\(password!)")
        //Firebase Authentication Process"

        FIRAuth.auth()?.signInWithEmail(email!, password: password!){ (user, error) in
            // ...
            if (error != nil){

                let errorCode = error!.code

                if (errorCode == 17009){

                    errorMsg = "You have entered the wrong password"

                } else if (errorCode == 17011){

                    errorMsg = "Your email does not exist"

                } else if (errorCode == 17010) {

                    errorMsg = "You have tried to login too many times with the wrong credentials. Please try again later."

                } else {

                    print(error)

                }

            } else {
                print("User is Logged In")
                errorMsg = "You have successfully Logged In"
            }


        }
        completion(message: errorMsg)

    }

}

}

登录视图控制器

import UIKit

class LoginViewController: UIViewController {

//Properties
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var emailTextField: UITextField!

//Actions
@IBAction func loginButton(sender: AnyObject) {

    let email = self.emailTextField.text!
    let password = self.passwordTextField.text!

    let user = UserLogin1(email: email, password: password)

    user.userLogin(){ (message:String) in
        print(message)
    }


    }

【问题讨论】:

  • 当您推测问题在于 signInWithEmail 是异步调用时,您是对的。这意味着当您返回消息时,登录功能甚至没有完成处理。您将能够使用completion handler 或仅在self. errorMsg 中设置您的消息来完成此操作。

标签: ios iphone swift firebase firebase-authentication


【解决方案1】:

根据我的评论,我提到您将有两种可能的解决方案。最佳选择将取决于您要达到的目标。但我相信你可以让它与他们中的任何一个一起工作。

Completion Handler

func userLogin(completion:(message:String)->()){
    var errorMsg:String = ""
    if (email == ""){
    ...
    //check if found any errors yet
    }else if (errorMsg != ""){
        completion(errorMsg)
    } else {
        FIRAuth.auth()?.signInWithEmail(email!, password: password!){ (user, error) in
            if (error != nil){
            ...
            } else {
                errorMsg = "You have successfully Logged In"
            }
            completion(errorMsg)
        }
    }
}

userLogin(){ (message:String) in
    // this will only be called when userLogin trigger completion(errorMsg)...
    print(message)
}

与自我

func userLogin() -> Void{
    var errorMsg:String = ""
    if (email == ""){
    ...
    //check if found any error yet
    }else if (errorMsg != ""){
        self.errorMsg = errorMsg
    } else {
        FIRAuth.auth()?.signInWithEmail(email!, password: password!){ (user, error) in
            if (error != nil){
            ...
            } else {
                errorMsg = "You have successfully Logged In"
            }
            self.errorMsg = errorMsg
        }
    }
}

【讨论】:

  • 嗨阿道夫!感谢您的回复。我真的很感激。我尝试了你的方法..对于self的第二部分,它一直返回我UserLogin没有errorMsg的成员..对于第二种方法,我实现它如下,虽然它没有返回任何错误,当我print(message) 什么都没有显示。我真的不知道我在哪里做错了......我把实现的代码留在下面,如果可能的话,我能麻烦你花点时间看看它并帮我看看为什么吗?谢谢!
  • @JacaiLau 你调试了吗? userLogin 是否被调用?尝试将completion(message: errorMsg) 替换为completion(errorMsg)
  • 我已经测试过并且正在调用 userLogin。奇怪的是,如果我输入了正确的电子邮件和密码,它仍然可以打印(“登录...使用电子邮件...)和打印(“用户已登录”),但错误消息没有填充。如果我改变它完成(errorMsg)它返回一个错误“在调用中缺少参数标签'消息'”
  • 哦,我想通了。我认为我完成的位置(消息:errorMsg)是错误的!谢谢阿道夫。你帮了大忙!!
  • @JiacaiLau 是的。它应该在 firebase 回调中。 (上面有一个})。欢迎您!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-09
  • 2014-12-16
  • 2012-12-26
  • 2014-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多