我已经进行了使用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)")
}
})
}
答案 0 :(得分:2)
这很简单。
您正在执行异步调用以检查userExists
和passwordIsValid
,但在进行if
测试之前,您不希望得到答案。
因此,第一次,completionHandler尚未完成,因此userExists
和passwordIsValid
设置为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
}
您的上述代码在usernameExists
和passwordIsValid
第一次获得任何值之前正在执行。所以把这个代码片段放在最终完成处理程序中,你的问题就会解决......!