编辑 UITextField 时检查用户名是否在 Firestore 数据库中

Check if username is in Firestore Database while editing UITextField

我正在尝试检查在用户键入名称时是否使用了用户名。目前我有这两个功能,它们几乎按照我希望的方式工作,但不是 100% 正确:

textFieldDidChange:

 @objc private func textFieldDidChange(_ textField: UITextField) {

    switch textField {

    // ... //    
    case usernameTextField:
        if textField.text?.isEmpty == false {
            checkUsername(field: textField.text!) { (success) in
                print(textField.text!)
                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"
                } else {
                    // username is not taken
                    print("Username is not taken")
                    self.checkUsernameImage.image = UIImage(named: "correct")
                    self.checkUserNameLabel.text = "gültiger Benutzername"
                }
            }
        }else {
            self.checkUsernameImage.image = UIImage(named: "false")
            self.checkUserNameLabel.text = "kein gültiger Benutzername"
        }
    default:
        break
    }

}


// helper function to check if username is in databse -> later in Datahandler
func checkUsername(field: String, completion: @escaping (Bool) -> Void) {

    let db = Firestore.firestore()
    let collectionRef = db.collection("users")
    collectionRef.whereField("username", isEqualTo: field).getDocuments { (snapshot, err) in
        if let err = err {
            print("Error getting document: \(err)")
        } else if (snapshot?.isEmpty)! {
            completion(false)
        } else {
            for document in (snapshot?.documents)! {
                if document.data()["username"] != nil {
                    completion(true)
                }
            }
        }
    }
}

问题: 如果您输入的内容非常快,或者如果您的互联网连接不是很好,它会显示 Username is not taken 而实际上是。

如果您查看 Instagram 应用程序,他们会以完美的方式做到这一点:

  1. 输入内容,速度更快
  2. 在您停止输入一秒钟后,loading indicator 会弹出,然后您才会收到反馈,无论用户名是否被占用
  3. loading indicator 处于活动状态时输入内容,它会停止,只有在您再次停止输入时才会重新开始。

我的问题:我如何意识到这一点???比如我怎么知道用户 "stops" 打字但 textField 仍然是 editing ?我用 shouldEndEditing 尝试过,但只有当 textfield 不再被选中时才有效,这不是我想要实现的。最后,我希望拥有与 Instagram 应用程序完全相同的流程。

关于如何实现这一点的任何想法?

在@Jays 的建议下我成功了:

我的 textFielddidChange 方法连接,如下所示:

timer.invalidate() // reset timer

// start the timer
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)

连接的 timerAction 方法如下所示:

// called every time interval from the timer
@objc func timerAction() {
    checkUsername(field: usernameTextField.text!) { (success) in
        print(self.usernameTextField.text!)
        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"
            // stop timer
            self.timer.invalidate()
        } else {
            // username is not taken
            print("Username is not taken")
            // stop timer
            self.timer.invalidate()
        }
    }
}

完全按照我想要的方式工作,感谢您的帮助:)