WaitUntilAllTasksAreFinished error 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 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 waitUntilAllTasksAreFinished],/SourceCache/UIKit_Sim/UIKit-3318.16.14/Keyboard/UIKeyboardTaskQueue.m:374 2014-11-15 17: 41: 29.540 Wavesss [8462: 846477] *** Завершение приложения из-за неперехваченного исключения "NSInternalInconsistencyException", причина: '- [UIKeyboardTaskQueue waitUntilAllTasksAreFinished] может вызываться только из основного потока.'
пожалуйста, помогите мне, хотя я изо всех сил пытаюсь найти решение для этого,
кажется, что я не могу проходить между контроллерами представлений, пока задача url все еще выполняется в другом потоке.
спасибо заранее, ребята!
Ответы
Ответ 1
Ваша функция 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)
}
}
}
Ответ 2
С Xcode 8.0 и Swift 3 это было изменено на следующую конструкцию:
OperationQueue.main.addOperation{
<your segue or function call>
}
Ответ 3
У меня тоже была такая же проблема, она была решена, взяв ссылку из ответа выше. Спасибо @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)
}
Ответ 4
У меня возникла эта проблема при попытке изменить содержимое текстового поля внутри задачи Async.
В решении использовалось DispatchQueue (Xcode 8.0 и Swift 3.0):
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.textBox.text = "Some Value"
}