swift - 等待回调函数完成 : Swift

标签 swift asynchronous callback

我想在用户从 LoginController 登录时更改 View 。当 access = true 时,更改 Controller 。但是,我不能在 user.login 中执行此操作,因为它给我一个错误,提示我必须在主线程上处理它。现在我知道有解决方案,但是我一直在寻找一个星期并且在圈子里跑来跑去。我已经足够接近,可以生成下面的内容了。

我想分享 3 条信息: 登录 Controller :

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")
        }

登录类:

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)
}

API管理器:

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

}

ANSWER : 请往下看更新的答案

请看@Rob 的回答。但是,您可能会收到一条错误消息,提示由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“-[UIKeyboardTaskQueue waitUntilAllTask​​sAreFinished] 只能从主线程调用。”。这是因为除非它在主线程上,否则您不能更改 View 。只需将其包裹在

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

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

最佳答案

无需等待响应,只需将要执行的代码移到闭包中即可:

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")
    }
}

关于swift - 等待回调函数完成 : Swift,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34027709/

相关文章:

ios - 无法将类型 '() -> Void' 的值分配给类型 '(() -> Void)!'

c# - 并行调用 IEnumerable 的元素

c# - 抑制警告 CS1998 : This async method lacks 'await'

c++ - 在 C++ 中是否有任何事件/委托(delegate)/接口(interface)/通知!任何事物?

javascript - 如何获取回调函数的所有参数

ios - 在没有 Mac OS 的情况下绑定(bind) Swift 库以在 Xamarin 中使用,这可能吗?

ios - 如何使用 Swift 在 LLDB 控制台中使用 _printHierarchy?

ios - 带有导致崩溃的约束的自定义 View (xib)

c# - 如何使我的自定义 TaskScheduler 成为默认任务调度程序

c - 如何将参数传递给回调函数以创建新函数?