CloudKit,我的身份验证无效

CloudKit, My Auth Not Working

我已经使用CloudKit中的记录进行了身份验证,所以我创建了一个帐户,然后转到我的登录页面并尝试登录,我第一次按登录时,它显示了我的错误消息"Username or Password was Incorrect",但是我第二次按下登录按钮时它起作用了。我真的不知道是什么原因造成的。

以下是我认为相关的代码:

func loginPressed() {

    validLogin()

    if usernameExists == true && passwordIsValid == true {
        performSegue(withIdentifier: "loginToGames", sender: self)
    } else {

        self.incorrectLabel.isHidden = false
    }
}



 func validLogin() {

    let container = CKContainer.default()
    let pubDB = container.publicCloudDatabase

    //query users to find current user
    let query = CKQuery(recordType: "MyUsers", predicate: Predicate(format: "TRUEPREDICATE", argumentArray: nil))
    pubDB.perform(query, inZoneWith: nil, completionHandler: { (records, error) in

        if error == nil {

            for record in records! {

                if record.object(forKey: "Username") as? String == self.usernameField.text {

                    self.incorrectLabel.isHidden = true
                    self.usernameExists = true
                    print("searchUsername \(record.object(forKey: "Username") as? String)")
                } else {

                    self.incorrectLabel.isHidden = false
                    self.usernameExists = false
                    print("searchUsername error")
                }

            }

        } else {
            print("searchLoginError\(error)")
        }
    })

    let queryPassword = CKQuery(recordType: "MyUsers", predicate: Predicate(format: "TRUEPREDICATE", argumentArray: nil))
    pubDB.perform(queryPassword, inZoneWith: nil, completionHandler: { (records, error) in

        if error == nil {

            for record in records! {

                if record.object(forKey: "Password") as? String == self.passwordField.text {

                    self.incorrectLabel.isHidden = true
                    self.passwordIsValid = true
                    print("searchPassword \(record.object(forKey: "Password") as? String)")
                } else {

                    self.incorrectLabel.isHidden = false
                    self.passwordIsValid = false
                    print("searchPassword error")
                }

            }

        } else {
            print("searcherror\(error)")
        }
    })

}

func checkValidLogin() {

    let container = CKContainer.default()
    let pubDB = container.publicCloudDatabase

    //query users to find current user
    let query = CKQuery(recordType: "MyUsers", predicate: Predicate(format: "TRUEPREDICATE", argumentArray: nil))
    pubDB.perform(query, inZoneWith: nil, completionHandler: { (records, error) in

        //we do not need to check for error code 11 because a user should exist
        if error == nil {

            var userExists = false

            for record in records! {

                if record.object(forKey: "Username") as? String == self.usernameField.text {

                    if record.object(forKey: "Password") as? String == self.passwordField.text {

                        OperationQueue.main.addOperation {

                            userExists = true
                            UserDefaults.standard.set(self.usernameField.text!, forKey: "Username")
                            username = self.usernameField.text!


                        }

                    } else {

                        //user with the username exists, but the password does not match
                        self.incorrectLabel.isHidden = false

                    }

                }

            }

            if userExists == false {

                //user with that username does not exist
                self.incorrectLabel.isHidden = false

            }


        } else {

            print("searcherror \(error)")

        }

    })

}

很简单。

您正在执行异步调用以检查 userExistspasswordIsValid,但您不想在进行 if 测试之前得到答案。

所以第一次,completionHandler没有结束,所以userExistspasswordIsValid设置为false。在第二次执行时,处理程序确实将值设置为 true.

您应该通过 if 测试作为 validLogin 函数的 completionHandler

样本:

func loginPressed() {

    validLogin() { (usernameExists, passwordIsValid) in 

        if usernameExists == true && passwordIsValid == true {
            performSegue(withIdentifier: "loginToGames", sender: self)
        } else {
            self.incorrectLabel.isHidden = false
        }
    }
}

func validLogin(completion : ((usernameExists : Bool, passwordIsValid : Bool) -> Void)) {

    let container = CKContainer.default()
    let pubDB = container.publicCloudDatabase
    let group = dispatch_group_create() //make sur both handler are triggered
    //query users to find current user

    dispatch_group_enter(group)
    let query = CKQuery(recordType: "MyUsers", predicate: Predicate(format: "TRUEPREDICATE", argumentArray: nil))
    pubDB.perform(query, inZoneWith: nil, completionHandler: { (records, error) in

        if error == nil {

            for record in records! {

                if record.object(forKey: "Username") as? String == self.usernameField.text {

                    self.incorrectLabel.isHidden = true
                    self.usernameExists = true
                    break
                } else {
                    self.incorrectLabel.isHidden = false
                    self.usernameExists = false
                }
            }

        } else {
            print("searchLoginError\(error)")
        }

        dispatch_group_leave(group)

    })

    dispatch_group_enter(group)
    let queryPassword = CKQuery(recordType: "MyUsers", predicate: Predicate(format: "TRUEPREDICATE", argumentArray: nil))
    pubDB.perform(queryPassword, inZoneWith: nil, completionHandler: { (records, error) in


        if error == nil {
            for record in records! {
                if record.object(forKey: "Password") as? String == self.passwordField.text {

                    self.incorrectLabel.isHidden = true
                    self.passwordIsValid = true
                    break
                } else {    
                    self.incorrectLabel.isHidden = false
                    self.passwordIsValid = false
                    print("searchPassword error")
                }

            }
        } else {
        print("searcherror\(error)")
        }
        dispatch_group_leave(group)

    })

    dispatch_group_notify(group, dispatch_get_main_queue()) {
    //You have both answers
        completion(self.usernameExists, passwordIsValid : self.passwordIsValid)

    })
}

在您的完成处理程序中写入以下部分,

    if usernameExists == true && passwordIsValid == true {
    performSegue(withIdentifier: "loginToGames", sender: self)
} else {

    self.incorrectLabel.isHidden = false
}

您的上述代码在 usernameExistspasswordIsValid 第一次获得任何值之前执行。所以将此代码片段放入最终完成处理程序中,您的问题将得到解决...!