等待回调函数完成:Swift

时间:2015-12-01 18:41:53

标签: swift asynchronous callback

我想在用户从LoginController登录时更改视图。当access = true时,更改控制器。但是,我无法在user.login中执行此操作,因为它给出了一个错误,说我必须在主线程上处理它。现在我知道有这方面的解决方案,但我一直在寻找一个星期并绕圈跑来跑去。我已经足够接近生产下面的东西了。

我想分享3条信息: 的LoginController:

var access = false
        user.login(
            {(response: Bool) -> () in
                access = response
                print(access)
            },username: emailField.text!, password: passwordField.text!)
        if(access){
            print("YAY")
            let controller = storyboard?.instantiateViewControllerWithIdentifier("NewsFeed") as! NewsFeed
            presentViewController(controller, animated: true, completion: nil)
        }else{
            print("NAY")
        }

LoginClass:

func login(completionHandler : (response: Bool) -> (), username: String, password: String){
    //Set the calback with the calback in the function parameter
    let parameters : [String: AnyObject] = ["tag": "login", "email": username, "password": password]
    manager.postDataToServer(
        {(response: NSDictionary) -> () in
            if(response["success"] as! Int == 1){
                // Log user in
            }else{
                // User not able to login

                }
                completionHandler(response: false)
            }
        }, page: "login", params: parameters)
}

APIManager:

func postDataToServer(completionHandler: (response: NSDictionary) -> (), page: String, params: [String: AnyObject]){
    // Gets the information and returns the User
    // Works completely fine

}

答案:请继续查看更新后的答案

请看@ Rob的回答。但是,您可能会收到一条错误消息,指出由于未捕获的异常终止应用程序' NSInternalInconsistencyException',原因:' - [UIKeyboardTaskQueue waitUntilAllTask​​sAreFinished]只能从主线程调用。' 。这是因为除非在主线程上,否则您无法更改视图。只需将其包装在

NSOperationQueue.mainQueue().addOperationWithBlock {
        //Change View
    } 

更新 我意识到我的错误是在处理信息之前我没有在我的一个字段中结束编辑。我通过执行以下操作修复了它:passwordField.endEditing以及emailField.endEditing(只是为了安全)

1 个答案:

答案 0 :(得分:2)

不要等待响应,只需移动要在闭包内执行的代码:

user.login( { response in
    if response {
        print("YAY")
        let controller = self.storyboard?.instantiateViewControllerWithIdentifier("NewsFeed") as! NewsFeed
        self.presentViewController(controller, animated: true, completion: nil)
    } else {
        print("NAY")
    }
}, username: emailField.text!, password: passwordField.text!)

更好的是,我会改变那些参数的顺序,因此闭包是最后一个参数(然后你可以使用“尾随闭包”语法):

func loginWithUsername(username: String, password: String, completionHandler : (response: Bool) -> ()) {
    // your login code here
}

然后:

user.loginWithUsername(emailField.text!, password: passwordField.text!) { response in
    if response {
        print("YAY")
        let controller = self.storyboard?.instantiateViewControllerWithIdentifier("NewsFeed") as! NewsFeed
        self.presentViewController(controller, animated: true, completion: nil)
    } else {
        print("NAY")
    }
}
相关问题