waitUntilAllTask​​sAreFinished错误Swift

时间:2014-11-15 15:50:41

标签: ios json http session swift

按下“提交”按钮时,我在loginViewController中调用了这个调用:

let http = HTTPHelper()
    http.post("http://someUrl.com/Login/userEmail/\(username.text)/Pswd/\(userPass.text)", postCompleted: self.checkLogin)

虽然我发送的checkLogin函数只执行:

func checkLogin(succeed: Bool, msg: String){
    if (succeed){
        self.performSegueWithIdentifier("logInTrue", sender: self)
    }
}

post函数是HTTPHelper类是:

func post(url : String, postCompleted : (succeeded: Bool, msg: String) -> ()) {
    var request = NSMutableURLRequest(URL: NSURL(string: url)!)
    var session = NSURLSession.sharedSession()
    request.HTTPMethod = "POST"
    var err: NSError?
     self.task = session.dataTaskWithURL(NSURL(string: url)!)  {(data, response, error) in
        var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
        var err: NSError?
        var json = NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments, error: &err) as? NSDictionary
        var msg = "No message"
        // Did the JSONObjectWithData constructor return an error? If so, log the error to the console
        if(err != nil) {
            let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
            postCompleted(succeeded: false, msg: "Error")
        }
        else {
            // The JSONObjectWithData constructor didn't return an error. But, we should still
            // check and make sure that json has a value using optional binding.
            if let parseJSON = json {
                // Okay, the parsedJSON is here, let's get the value for 'success' out of it
                if let success = parseJSON["result"] as? Bool {
                    postCompleted(succeeded: success, msg: "Logged in.")
                }
                return
            }
            else {
                // Woa, okay the json object was nil, something went worng. Maybe the server isn't running?
                let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
                postCompleted(succeeded: false, msg: "Error")
            }
        }
    }

    self.task!.resume()
}

当成功调用checkLogin函数时:true它无法执行SegueWithIdentified函数。 错误看起来像:

  

断言失败 - [UIKeyboardTaskQueue waitUntilAllTask​​sAreFinished],/ SourceCache / UIKit_Sim / UIKit-3318.16.14 / Keyboard / UIKeyboardTaskQueue.m:374   2014-11-15 17:41:29.540 Wavesss [8462:846477] ***由于未捕获的异常终止应用程序' NSInternalInconsistencyException',原因:' - [UIKeyboardTaskQueue waitUntilAllTask​​sAreFinished]可能只能从主线。'

请帮助我,虽然我很难找到解决方案, 似乎我无法在视图控制器之间传递,而url任务仍然在其他线程上执行。 先谢谢你们!

4 个答案:

答案 0 :(得分:64)

您的checkLogin函数正在另一个线程上调用,因此您需要切换回主线程才能调用self.performSegueWithIdentifier。我更喜欢使用NSOperationQueue

func checkLogin(succeed: Bool, msg: String) {
    if (succeed) {
        NSOperationQueue.mainQueue().addOperationWithBlock {
            self.performSegueWithIdentifier("logInTrue", sender: self)
        }        
    }
}

备用:xCode 10.1 1/2019

func checkLogin(succeed: Bool, msg: String) {
    if (succeed) {
        OperationQueue.main.addOperation {
            self.performSegue(withIdentifier: "logInTrue", sender: self)
           }        
      }
 }

答案 1 :(得分:16)

使用Xcode 8.0和Swift 3,它已被修改为以下构造:

  <script   src="https://code.jquery.com/jquery-3.1.1.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src='https://www.google.com/recaptcha/api.js'></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/fotorama/4.6.4/fotorama.js"></script> 

答案 2 :(得分:2)

我也遇到了同样的问题,从上面的回答中得到了解决。谢谢@Nate

var storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var vc: UINavigationController = storyBoard.instantiateViewControllerWithIdentifier("AppViewController") as! UINavigationController

NSOperationQueue.mainQueue().addOperationWithBlock {
    self.presentViewController(vc, animated: true, completion: nil)
}

答案 3 :(得分:0)

尝试从异步任务内部更改文本框的内容时遇到此问题。

解决方案是使用DispatchQueue(Xcode 8.0和Swift 3.0):

    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
       self.textBox.text = "Some Value"
       }