我该如何处理shouldPerformSegueWithIdentifier中的Alamofire响应?

时间:2015-01-28 13:34:33

标签: swift segue uistoryboard uistoryboardsegue alamofire

我正在尝试学习Swift,我想要做的是创建简单的登录页面。每当用户单击登录按钮时,我都会在shouldPerformSegueWithIdentifier中向我的Web服务发出请求,以检查用户名和密码是否正确。我不想使用IBAction(如touchupinside等)。解析来自Web服务的响应后,我检查Web服务响应是否有任何错误(如用户名无效)。如果有任何错误,我想通过返回false来阻止segue。但我无法在Alamofire内部回归虚假。那我该怎么处理呢?这是我的代码:

override func shouldPerformSegueWithIdentifier(identifier: String?, sender: AnyObject?) -> Bool {

    if identifier == "segueLoginToMainPage" {
        //...
        //Checking if text fields are filled or not

        else {
            let callURL : String = CONFIG.BASE_URL + "user/login"
            let parameters = [HTTPParamNames.FIELD_USER_NAME : self.txtUserName.text,
                            HTTPParamNames.FIELD_PASSWORD : self.txtPassword.text]
            Alamofire.request(.POST, callURL, parameters: parameters)
                .responseJSON { (_,_,JSON,_) in
                    var returnedData = JSON as NSDictionary
                    if returnedData["status"] as String == "error" {

                        //thats what i want to do
                        return false 
                    }
                }

        }
    }

    return true
}

但我不能返回false,因为它是异步的。我在stackoverflow中发现了一些像这样的问题,但答案并不是我想要的。谢谢!

2 个答案:

答案 0 :(得分:8)

您根本不应该尝试在shouldPerformSegueWithIdentifier中使用异步方法。相反,你应该:

  1. 从登录按钮中删除segue本身。

  2. 在视图控制器之间添加segue。具体来说, control -drag来自原始场景的视图控制器图标(在Xcode 6+中,此图标位于场景上方的栏中,在早期版本的Xcode中,此图标位于场景下方的栏目)到目的地场景。

  3. 为这个新的segue提供一个"故事板标识符"。

  4. 将登录按钮连接到IBAction功能。

  5. 在该IBAction函数中,执行异步网络请求,如果登录成功,则以编程方式performSegueWithIdentifier,提供您在步骤3中指定的情节提要标识符。

答案 1 :(得分:1)

我认为在这种情况下不使用IBAction是一个很好的解决方案,但无论如何,有一个解决方法如何实现您的目标。对于此变通方法,您需要声明一个变量类型布尔值来检查用户是否已准备好登录。您的shouldPerformSegueWithIdentifier方法应该始终返回该变量的值,但是在您发出请求之后。最后,在异步请求完成后调用prepareForSegue方法

var readyForLogin = false

override func shouldPerformSegueWithIdentifier(identifier: String?, sender: AnyObject?) -> Bool {

if identifier == "segueLoginToMainPage" {
    //...
    //Checking if text fields are filled or not

    else  {
        if(!readyForLogin){
            let callURL : String = CONFIG.BASE_URL + "user/login"
            let parameters = [HTTPParamNames.FIELD_USER_NAME : self.txtUserName.text,
                        HTTPParamNames.FIELD_PASSWORD : self.txtPassword.text]
            Alamofire.request(.POST, callURL, parameters: parameters)
            .responseJSON { (_,_,JSON,_) in
                var returnedData = JSON as NSDictionary
                if returnedData["status"] as String != "error" {
                    //thats what i want to do
                    self.readyForLogin = true
                    self.performSegueWithIdentifier("segueLoginToMainPage", sender: self)
                }
            }

    }}
}

return readyForLogin
}