2014-11-15 26 views
31

ho questa chiamata nel mio loginViewController quando il pulsante Invia viene premuto:errore waitUntilAllTasksAreFinished Swift

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

mentre la funzione checkLogin mando è solo eseguendo:

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

il post è HTTPHelper classe è :

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

quando la funzione checkLogin viene richiamata con successo s: true non riesce a performSegueWithIdentified funzione .. l'errore si presenta come:

errore di asserzione in - [UIKeyboardTaskQueue waitUntilAllTasksAreFinished], /SourceCache/UIKit_Sim/UIKit-3318.16.14/Keyboard/UIKeyboardTaskQueue.m:374 2014-11-15 17: 41: 29.540 Wavesss [8462: 846477] *** Termine dell'app a causa dell'eccezione non rilevata 'NSInternalInconsistencyException', motivo: '- [UIKeyboardTaskQueue waitUntilAllTasksAreFinished] può essere chiamato solo dal thread principale.'

aiutarmi se io sto lottando molto difficile trovare una soluzione per questo, sembra che non posso passare tra i controller di vista, mentre il compito url è ancora in corso su un altro thread. grazie in anticipo ragazzi!

risposta

59

La tua funzione checkLogin viene chiamata su un altro thread, quindi è necessario tornare al thread principale prima di chiamare self.performSegueWithIdentifier. Io preferisco usare NSOperationQueue:

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

ho dovuto mettere questo: OperationQueue.main.addOperation { – Isabelle

1

ero anche avendo lo stesso problema, ma ho risolto prendendo riferimento dall'alto risposta. Grazie @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) 
} 
14

con Xcode 8.0 e Swift 3, questo è stato modificato al seguente costrutto:

OperationQueue.main.addOperation{ 
    <your segue or function call> 
} 
0

ho avuto questo problema quando si cerca di modificare il contenuto di una casella di testo da all'interno di un'attività asincrona.

La soluzione stava usando il DispatchQueue (Xcode 8.0 e Swift 3.0):

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