Ios restful回调上的xcode当前序列(swift)

Ios restful回调上的xcode当前序列(swift),ios,iphone,swift,xcode6,segue,Ios,Iphone,Swift,Xcode6,Segue,我是自学成才的Swift用户,试图做一些简单的事情,但这让我很困惑。我有一张简单的登记表。提交要注册的项目后,我希望通过segue将页面移动到“它是如何工作的”页面,但仅当我的restfulapi返回success时。这是我到目前为止所拥有的;请随时给我一个更好的方法来做到这一点。欢迎所有批评 let myUrl = NSURL(string:"http://www.example.com/scripts/Register.php") let request = NSMutableURLRequ

我是自学成才的Swift用户,试图做一些简单的事情,但这让我很困惑。我有一张简单的登记表。提交要注册的项目后,我希望通过segue将页面移动到“它是如何工作的”页面,但仅当我的restfulapi返回success时。这是我到目前为止所拥有的;请随时给我一个更好的方法来做到这一点。欢迎所有批评

let myUrl = NSURL(string:"http://www.example.com/scripts/Register.php")
let request = NSMutableURLRequest(URL: myUrl!)
request.HTTPMethod = "POST"

let postString = "email=\(email)&password=\(pass)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)

let task = NSURLSession.sharedSession().dataTaskWithRequest(request){
    data, response, error in

    if (error != nil) {
        println("Error: \(error)")
        return
    }

    var err: NSError?
    var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: &err) as? NSDictionary
    var showTutorial : Bool = false

    if let parseJSON = json {
        var returnValue = parseJSON["status"] as? String
        println("Status: \(returnValue)")

        var isUserRegistered: Bool = false
        if (returnValue == "Success") {
            showTutorial = true
        } else if (returnValue == "Error") {                    
            // handle error
        }
    }

    // if successful registration, show how it works page
    if (showTutorial) {
        self.performSegueWithIdentifier("howItWorksSegue", sender: self)
    }
}
task.resume()
我有一个名为
howItWorksSegue
的segue附加到此视图控制器,并转到
HowItWorksViewController
。我从Xcode收到此错误:

2015-10-12 21:22:43.261 ZiftDine[11396:2307755]在-[UIKeyboardTaskQueue WaitUntillallTasksRefiefined],/SourceCache/UIKit_Sim/UIKit-3347.44.2/Keyboard/UIKeyboardTaskQueue.m:374中断言失败
2015-10-12 21:22:43.391 ZiftDine[11396:2307755]由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“-[UIKeyboardTaskQueue WaituntlallTasksRefiefined]只能从主线程调用。”


使用UI完成的任何操作都应在主线程上完成,请尝试按如下方式包装您的performSegue调用:

dispatch_async(dispatch_get_main_queue(),{
    self.performSegueWithIdentifier("howItWorksSegue", sender: self)
})

使用UI完成的任何操作都应在主线程上完成,请尝试按如下方式包装您的performSegue调用:

dispatch_async(dispatch_get_main_queue(),{
    self.performSegueWithIdentifier("howItWorksSegue", sender: self)
})

@Swinny89给出了你问题的解决方案,但有些解释是正确的

如果您阅读了
dataTaskWithRequest:completionHandler:
的描述,这是您正在使用的方法(尽管您的Swift代码使用尾部闭包语法删除
completionHandler
标签并将闭包放在括号外),它会说:

completionHandler:加载时要调用的完成处理程序 请求已完成。此处理程序在委托队列上执行

然后,如果您阅读init方法
sessionWithConfiguration:delegate:delegateQueue:
的描述,它会说:

队列:用于安排代理调用和完成的队列 处理程序。如果为nil,会话将为创建一个串行操作队列 执行所有委托方法调用和完成处理程序调用

串行操作队列在不同的线程上运行

因此,将所有这些信息放在一起,这意味着您的完成闭包将在主线程以外的线程上执行

iOS/Mac开发的一条基本规则是,必须从主线程执行所有UI调用。如果一个调用改变了屏幕上的任何内容,那就是UI调用

您的代码正在从后台线程调用
performsguewithidentifier:
。它改变了屏幕上显示的内容,因此它必须是一个UI调用。因此,它需要在主线程上运行

GCD函数
dispatch\u async()
,队列为
dispatch\u get\u main\u queue()
,它提交一个闭包以在主调度队列上运行,该队列在主线程上运行

斯温尼的解决方案解决了你的问题

外卖在这里:


每当您在闭包中运行代码时,停下来想一想:“我确定此闭包将始终在主线程上运行吗?”如果答案是否,请将代码包含在调用
dispatch\u async(dispatch\u get\u main\u queue()的过程中
,就像斯温尼的回答。

@Swinny89给出了问题的解决方案,但有些解释是正确的

如果您阅读了
dataTaskWithRequest:completionHandler:
的描述,这是您正在使用的方法(尽管您的Swift代码使用尾部闭包语法删除
completionHandler
标签并将闭包放在括号外),它会说:

completionHandler:加载时要调用的完成处理程序 请求已完成。此处理程序在委托队列上执行

然后,如果您阅读init方法
sessionWithConfiguration:delegate:delegateQueue:
的描述,它会说:

队列:用于安排代理调用和完成的队列 如果为nil,会话将为创建一个串行操作队列 执行所有委托方法调用和完成处理程序调用

串行操作队列在不同的线程上运行

因此,将所有这些信息放在一起,这意味着您的完成闭包将在主线程以外的线程上执行

iOS/Mac开发的一条基本规则是,您必须从主线程执行所有UI调用。如果某个调用改变了屏幕上的任何内容,那么它就是UI调用

您的代码正在从后台线程调用
performsguewithidentifier:
。它会更改屏幕上显示的内容,因此它必须是UI调用。因此需要在主线程上运行

GCD函数
dispatch\u async()
,队列为
dispatch\u get\u main\u queue()
,它提交一个闭包以在主调度队列上运行,该队列在主线程上运行

斯温尼的解决方案解决了你的问题

外卖在这里:


每当您在闭包中运行代码时,停下来想一想:“我确定此闭包将始终在主线程上运行吗?”如果答案是否,请将代码包含在调用
dispatch\u async(dispatch\u get\u main\u queue()的过程中
,就像斯文尼的答案一样。

邓肯C和斯文尼89的答案很好。对于来自谷歌的任何人来说,斯文尼3的语法有一点变化:

DispatchQueue.main.async(execute: {
    self.performSegueWithIdentifier("howItWorksSegue", sender: self)
})

@Duncan C和@Swinny89给出的答案很好。对于来自谷歌的任何人来说,Swift 3中的语法有点变化:

DispatchQueue.main.async(execute: {
    self.performSegueWithIdentifier("howItWorksSegue", sender: self)
})

谢谢。事实上我刚刚试过,效果很好。不过我仍然想知道这是否是一个很好的方法。这正是解决这个问题的正确方法:)我经常使用它。如果它回答了你的问题,请标记为answered@Swinny89谢谢分享这个-我刚刚开始使用swift,这让我的生活变得轻松了很多!谢谢。我实际上刚刚尝试过它,它很管用。但仍然想知道这是否是一个好方法。它是