返回Firebase用户名时出现iOS异步任务问题

时间:2016-07-30 22:50:16

标签: ios swift asynchronous firebase-authentication

我非常接近完成项目的这一部分。我已经学到了很多东西,但却看不出来,把它包起来。我想要做的是基本上检查一个电子邮件地址是否已被其他用户使用。为此,我使用此代码:

$GOPATH

整个func emailCheck(input : String, result:(canRegister: Bool?) -> Void){ var canRegister : Bool? FIRAuth.auth()?.signInWithEmail(input, password: " "){(user, error) in if error != nil { if(error?.code == 17009){ print("Wrong Password") canRegister = false }else if(error?.code == 17011){ print("Unknown User") canRegister = true }else{ canRegister = false } } } } 对我来说只有6个小时,所以如果您有任何建议请告诉我。但是当按下按钮时会调用此函数,只需执行以下操作:

Async

出于某种原因,这是空的,而不是print(emailCheck(emailTxt.text!){(canRegister : Bool?) -> Void in}) true甚至是false。它只返回nil但是当我传入正确的密码时它会返回(),不太确定这是否相关。任何人都可以帮忙吗?谢谢大家!

添加了信息 建议之后,代码和对代码的引用现在看起来像这样:(仅包含重要部分)

Wrong Password

这背后的过程是,如果返回的代码是用户不存在,那么电子邮件帐户将被打开以被拒绝,从而允许class LoginViewController: UIViewController { @IBAction func nextScreen(sender: UIButton) { emailCheck(emailTxt.text!) { isValid in if isValid { print("Valid!") } else { print("Invalid!") } } } func emailCheck(input: String, callback: (isValid: Bool) -> Void) { FIRAuth.auth()?.signInWithEmail(input, password: "") { (user, error) in var canRegister = false if error != nil { if (error?.code == 17009) { //wrong password error } else if(error?.code == 17011) { //email doesn't exist canRegister = true } } callback(isValid: canRegister) } } ,否则,如果空密码传入它是不正确的,然后我们知道该帐户存在,因此不能开放使用。目前,canRegister返回的值等于此处定义的值:

canRegister

返回函数调用。

1 个答案:

答案 0 :(得分:1)

您正在打印emailCheck的返回值,这不是您想要的。异步只是意味着部分代码将在以后运行。考虑这个简单的功能:

func emailCheck(input: String) -> Bool {
  var valid = true

  if input.characters.count == 0 {
    valid = false
  }

  return valid
}

这只是检查电子邮件的字符数是否超过零。它可以大大简化,但我已经说明了差异更加冗长。要使用它,您只需执行以下操作:

let isValid = emailCheck("me@example.com")

if isValid {
    print("Valid!")
} else {
    print("Invalid!")
}

如果我们希望该方法能够异步工作,我们会为它提供一个回调。回调只是一个函数,可以调用它来让我们知道结果是什么,而不是由函数直接返回它们。这是看起来像:

func emailCheck(input: String, callback: (isValid: Bool) -> Void) {
    var valid = true

    if input.characters.count == 0 {
        valid = false
    }

    callback(isValid: valid)
}

func callback(isValid: Bool) {
    if isValid {
        print("Valid!")
    } else {
        print("Invalid!")
    }
}

emailCheck("me@example.com", callback: callback)

请注意,emailCheck不再返回值,但实际上会使用结果执行回调方法。这不是真正的异步,因为回调是立即执行的,但如果我们愿意,它可以让我们做异步事情。

Swift有一些简洁的语法糖用于传递回调作为最后一个参数,而不像我上面那样明确地声明它们。这就是您用于Firebase的signInWithEmail方法的内容。在此代码中使用它,它看起来像这样:

emailCheck("me@example.com") { isValid in
    if isValid {
        print("Valid!")
    } else {
        print("Invalid!")
    }
}

它完全相同,但我认为在这种情况下它看起来更好一些。所以现在我们有一个可以检查电子邮件的好设置,以及一旦我们知道电子邮件是否有效就可以运行的一些代码。把它们放在一起:

func emailCheck(input: String, callback: (isValid: Bool) -> Void) {
    FIRAuth.auth()?.signInWithEmail(input, password: " ") { (user, error) in
        var canRegister = false

        if error != nil {
            if (error?.code == 17009) {
                print("Wrong Password")
            } else if(error?.code == 17011) {
                print("Unknown User")
                canRegister = true
            }
        }

        callback(isValid: canRegister)
    }
}


var availableEmail = false

emailCheck("me@example.com") { isValid in
    if isValid {
        print("Valid!")
    } else {
        print("Invalid!")
    }

    availableEmail = isValid
    // This prints **second**, and should print `true`, if `isValid` was true.
    print(availableEmail)
}

// This prints **first**, and should print `false`, because the callback likely has not run yet.
print(availableEmail)

修改:请参阅上面的print代码/注释,说明在使用回调方法时如何立即更新变量。

其他修改:构建它的另一种方法,为清晰起见使用其他功能:

emailCheck("me@example.com") { isValid in
    if isValid {
        print("Valid!")
    } else {
        print("Invalid!")
    }

    self.emailCheckComplete(isValid)
}

func emailCheckComplete(availableEmail: Bool) {
    // This is the same as above, but perhaps helps you follow the flow.
    print(availableEmail)
}