如果用户不存在,则应显示带有UIAlert的错误消息

时间:2017-01-01 13:00:02

标签: ios swift3

我目前正在使用Swift 3开发IOS应用程序。我正在使用登录系统。登录验证工作正常。逻辑是,如果登录成功,它将进入下一个屏幕。但是,如果用户不存在,则应显示UIAlert的错误消息。但是当我尝试显示UIAlert时,我收到一条错误,上面写着"断言失败 - [UIKeyboardTaskQueue waitUntilAllTask​​sAreFinished]"

//Getting data from database
    func getData() -> Void {

        let url: String = "http://localhost/fridge_app/login.php" //this will be changed to the path where service.php lives

        //created NSURL
        let requestURL = NSURL(string: url)

        //creating NSMutableURLRequest
        var request = URLRequest(url: requestURL! as URL)

        //setting the method to post
        request.httpMethod = "POST"


        //Getting values from textfield
        let usernameVal = username.text
        let passwordVal = password.text

        //creating the post parameter by concatenating the keys and values from text field
        let postString = "username=\(usernameVal!)&password=\(passwordVal!)";
        print(postString)
        request.httpBody = postString.data(using: String.Encoding.utf8)

        //creating a task to send the post request
        let task = URLSession.shared.dataTask(with: request as URLRequest){
            data, response, error in

            //exiting if there is some error
            if error != nil{
                print("error is \(error)")
                return;
            }

            // Print out response string
            var responseString: NSString?;
            responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
            if(responseString == "invalid"){
                self.isValid = false;
                print(self.isValid)
            }

            if self.checkLogin(data: responseString!) == true {
                self.performSegue(withIdentifier: "profileViewController", sender: self)
            }
            else{
                print("Hello")
                // It prints hello fine, but when it tries to run the showAlert function it fails
                self.showAlert()
            }


            //print("responseString = \(self.responseString)")

        }

        //executing the task
        task.resume()
   }

这是警报功能

/*
     * Show UIAlert Message
     */
    func showAlert() -> Void{
        let alert = UIAlertController(title: "User Does Not Exist",
                                      message: "",
                                      preferredStyle: UIAlertControllerStyle.alert)
        let loginFail = UIAlertAction(title: "Close", style: .default, handler: nil);

        alert.addAction(loginFail);
        present(alert, animated: true)

    }

当用户单击登录时调用此方法。

1 个答案:

答案 0 :(得分:3)

除非您采取特殊步骤,否则您提交给NSURLSession的任务的完成处理程序将在后台线程上运行。这意味着您所做的任何UI调用都必须发送到主线程,否则他们无法正常工作(并可能导致您的应用崩溃。)

完成处理程序中的代码执行的UI工作比调用警报要多。你也在调用一个segue。如果你的完成处理程序没有做很费时间的工作,你可能想要将整个事情包装在对主线程的GCD调用中:

DispatchQueue.main.async() {
  //Put the entire body of your completion handler in here
}

否则,您需要在如上所述的主队列调用中单独包装每个UI调用。

编辑:

查看您的特定完成处理程序,您有一个if / then / else块执行UIKit调用:

if self.checkLogin(data: responseString!) {  
  self.performSegue(withIdentifier: "profileViewController", 
    sender: self)
} else {
  print("Hello")
  self.showAlert()
}

所以只需将该部分包装在对主队列的调用中:

DispatchQueue.main.async() {
  if self.checkLogin(data: responseString!) {  
    self.performSegue(withIdentifier: "profileViewController", 
      sender: self)
  } else {
    print("Hello")
    self.showAlert()
  }
}