2016-09-13 5 views
1

Я сделал аутентификацию, которая использует записи в CloudKit, поэтому я сделал учетную запись, затем перешел на мою страницу входа и попытался войти в систему, когда я впервые нажал логин, он показал мое сообщение об ошибке " Имя пользователя или пароль были неверными ", однако во второй раз я нажимаю кнопку входа в систему, это работает. Я действительно не знаю, что вызывает это.CloudKit, My Auth Not Working

Вот что я считаю соответствующий код:

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

Это довольно просто.

Выполнение асинхронного вызова для проверки userExists и passwordIsValid, но вы не хотите отвечать перед тем, как выполнить свой тест if.

Итак, первый раз, завершениеHandler не закончено, поэтому userExists и passwordIsValid установлены на false. При втором выполнении обработчик установил значение true.

Вы должны пройти свой if тест как completionHandler для функции validLogin

Пример:

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) 

    }) 
} 
+0

Извините, где это следует добавить? Я новичок в кодировании. – RufusV

1

Написать ниже части в обработчике завершения,

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

    self.incorrectLabel.isHidden = false 
} 

ваш выше код становится выполнение перед usernameExists и passwordIsValid получение значения в первый раз. поэтому поставьте этот фрагмент кода в обработчике окончательного завершения и ваша проблема будет решена ...!

+0

Извините, где именно это нужно добавить? Я новичок в кодировании. – RufusV