CloudKit,我的身份验证不起作用

时间:2016-09-13 12:59:20

标签: ios swift authentication cloudkit

我已经进行了使用CloudKit中的记录的身份验证,所以我创建了一个帐户,然后进入我的登录页面并尝试登录,第一次按下登录时,它显示了我的错误消息"用户名或密码是不正确"但是第二次按下登录按钮它可以正常工作。我真的不知道造成这种情况的原因。

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

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)")

        }

    })

}

2 个答案:

答案 0 :(得分:2)

这很简单。

您正在执行异步调用以检查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)

    })
}

答案 1 :(得分:1)

在完成处理程序中写下部分,

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

    self.incorrectLabel.isHidden = false
}

您的上述代码在usernameExistspasswordIsValid第一次获得任何值之前正在执行。所以把这个代码片段放在最终完成处理程序中,你的问题就会解决......!