【问题标题】:Method continues even though data is still loading from Cloud Firestore即使仍在从 Cloud Firestore 加载数据,方法也会继续
【发布时间】:2020-03-09 18:34:25
【问题描述】:

我的应用程序出现问题,我有一个名为 signUpButtonTapped 的方法:

 @objc func signUpButtonTapped(_ sender: Any) {


    if !areFieldsValid()! {
        // some error in textfield
        theScrollView.scrollToTop()
    }else { /* create user */ }

如您所见,我调用了 areFieldsValid() 方法,它会检查我所有的 textFields 包括是否使用用户名:

//MARK: Validate Fields
func areFieldsValid() ->Bool? {

    var isValid = true

    // check if username is valid
    checkUsername(field: usernameTextField.text!) { (success) in
        if success == true {
            // username is taken
            print("Username is taken")
            self.setupUsernameTextField()
            self.checkUsernameImage.image = UIImage(named: "false")
            self.checkUserNameLabel.text = "Benutzername ist bereits vergeben"
            isValid = false
        }
    }

    return isValid
}

我遇到的问题是,即使用户名已经被使用,用户也会被创建,areFieldsValid 实际上应该返回false,但程序仍然继续...... 我猜这是因为程序继续时数据仍在加载?我不知道如何解决这个问题,所以我很感激每一个帮助!

【问题讨论】:

  • checkUsername 是一个异步函数,您可以看到它不是返回布尔值,而是给它一个完成处理程序,该处理程序在 success 参数中传递。因此,您的 areFieldsValid 函数也需要是异步的,并且需要一个完成处理程序。这些信息足以让您朝着正确的方向寻找吗?
  • @KevinRenskers 感谢您的帮助!有了这个和 Ivans 的回答,我设法解决了这个问题!

标签: ios swift firebase google-cloud-firestore


【解决方案1】:

您对网络的调用是异步的,这意味着它可以在未来的任何时间结束。异步调用只是开始运行并立即返回,当它们完成时调用一个完成块(在您的情况下,使用 success 布尔标志)。

在这种情况下,您对areFieldsValid() 的定义不正确,因为它期望返回异步调用的结果(立即返回)。你的验证函数应该有一个完成闭包来处理东西,像这样:

func validateFields(completion: @escaping (Bool) -> Void) {
    checkUsername(field: usernameTextField.text!) { success in
        if success {
            // username is taken
            print("Username is taken")
            self.setupUsernameTextField()
            self.checkUsernameImage.image = UIImage(named: "false")
            self.checkUserNameLabel.text = "Benutzername ist bereits vergeben"
            self.isValid = false
        }

        completion(success) // call the completion closure with the success status
    }
}

所以你可以这样称呼它:

@objc func signUpButtonTapped(_ sender: Any) {
    validateFields { areValid in
        if areValid {
            self.theScrollView.scrollToTop()
        } else {
            // create user
        }
    }
}

【讨论】:

  • 感谢您的回答!如果我理解正确,我不再需要validateFields 中的变量isValid 了,对吧?而signUpBUttonTapped()里面的areValid到底是什么意思?
  • areValidsuccess 的值相同(您将其传递回completion(success))。
  • 好的,明白了。我遇到的另一个问题是,在validateFields 内部,我还有几个要检查的标准,在您进行更改之前,我刚刚将isValid 更改为false,但这不再影响我的功能。我该如何解决?
  • 已修复 :) 我声明 isValid 取消了该功能,并在调用 validateFields 状态后进行了检查。感谢您的帮助:)
猜你喜欢
  • 1970-01-01
  • 2014-01-14
  • 2019-09-21
  • 1970-01-01
  • 2021-06-19
  • 1970-01-01
  • 2017-04-10
  • 2013-12-18
  • 1970-01-01
相关资源
最近更新 更多