2014-11-15 4 views
31

Ich habe diesen Anruf in meinem loginViewController wenn Senden-Taste gedrückt wird:waitUntilAllTasksAreFinished Fehler Swift

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

während die checkLogin Funktion, die ich nur senden ausführt:

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

die Post-Funktion ist HTTPHelper Klasse :

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

Wenn die checkLogin-Funktion mit Erfolg aufgerufen wird s: true es nicht Funktion performSegueWithIdentified .. der Fehler wie folgt aussieht:

Assertionsfehler in - [UIKeyboardTaskQueue waitUntilAllTasksAreFinished], /SourceCache/UIKit_Sim/UIKit-3318.16.14/Keyboard/UIKeyboardTaskQueue.m:374 2014-11-15 17: 41: 29.540 Wavess [8462: 846477] *** Beenden der App aufgrund der nicht abgefangenen Ausnahme 'NSInternalInconsistencyException', Grund: '- [UIKeyboardTaskQueue waitUntilAllTasksAreFinished] kann nur vom Hauptthread aus aufgerufen werden.'

mir bitte helfen, obwohl ich sehr hart bin kämpfen, um eine Lösung für diese zu finden, scheint es, wie ich nicht zwischen View-Controller, während die URL Aufgabe noch auf anderen Thread ausgeführt wird, wird passieren kann. danke im Voraus Jungs!

Antwort

59

Ihre checkLogin-Funktion wird an einem anderen Thread aufgerufen, daher müssen Sie zurück zum Hauptthread wechseln, bevor Sie self.performSegueWithIdentifier aufrufen können. Ich ziehe es NSOperationQueue verwenden:

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

Ich hatte dieses setzen – Isabelle

1

ich auch gleiches Problem aufwies, wurde beschlossen hätte Referenz genommen von oben Antwort. Danke @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

Mit Xcode 8.0 und Swift 3, hat dies auf die folgende Konstrukt modifiziert worden:

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

ich dieses Problem hatte, wenn sie versuchen, den Inhalt eines Textfeldes zu ändern aus in einer Async-Aufgabe.

Die Lösung wurde die DispatchQueue (Xcode 8.0 und Swift 3.0) mit: OperationQueue.main.addOperation {:

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