A function can only be called in the main thread, why?

In this code below, I call the displayMyAlertMessage () function twice. the first thing I call works fine, but the second gives me an error saying that the function can only be called from the main thread. How can I do this in my situation?

I am using this code:

@IBAction func loginButtonTapped(sender: AnyObject) { result2Value = "" let userEmail = userEmailTextField.text let userPassword = userPasswordTextField.text if userPassword.isEmpty || userPassword.isEmpty { displayMyAlertMessage("All fields are required") return; } //send user data to server side let myUrl = NSURL(string: "http://www.avanta.com/extra/test-userLogin.php") let request = NSMutableURLRequest(URL:myUrl!) request.HTTPMethod = "POST" let postString = "email=\(userEmail)&password=\(userPassword)" 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 if let parseJSON = json { var resultValue:String = parseJSON["status"] as! String! println("result: \(resultValue)") if (resultValue == "Success") { //login succesful NSUserDefaults.standardUserDefaults().setBool(true, forKey: "isUserLogin") NSUserDefaults.standardUserDefaults().synchronize() self.dismissViewControllerAnimated(true, completion: nil) // return } else{ self.displayMyAlertMessage("Wrong name or password") } } } task.resume() } 

To call this function:

 func displayMyAlertMessage(userMessage:String){ var myAlert = UIAlertController(title:"Alert", message:userMessage, preferredStyle: UIAlertControllerStyle.Alert) let okAction = UIAlertAction(title:"Ok", style:UIAlertActionStyle.Default, handler:nil) myAlert.addAction(okAction) self.presentViewController(myAlert, animated:true, completion:nil) } 

The error I get is:

 2015-06-20 14:44:41.646 UserLoginAndRegistration[6064:750474] *** Assertion failure in -[UIKeyboardTaskQueue waitUntilAllTasksAreFinished], /SourceCache/UIKit/UIKit-3318.16.14/Keyboard/UIKeyboardTaskQueue.m:374 2015-06-20 14:44:41.657 UserLoginAndRegistration[6064:750474] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '- [UIKeyboardTaskQueue waitUntilAllTasksAreFinished] may only be called from the main thread.' *** First throw call stack: (0x186551e48 0x196c4c0e4 0x186551d08 0x1873d5554 0x18ad2b0a8 0x18ad2b734 0x18ad24a1c 0x18b251564 0x18b0156a8 0x18b0169e4 0x18b0188dc 0x18adee0b4 0x100028f9c 0x10002b500 0x10002b5f4 0x10002b624 0x10002b68c 0x185ee6540 0x187407508 0x187358c94 0x18734861c 0x18740a26c 0x1005a4df0 0x1005af854 0x1005a8120 0x1005b175c 0x1005b2f18 0x19746d2e4 0x19746cfa8) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb) 0x18b251564 0x18b0156a8 0x18b0169e4 0x18b0188dc 0x18adee0b4 0x100028f9c 0x10002b500 0x10002b5f4 0x10002b624 0x10002b68c 0x185ee6540 0x187407508 0x187358c94 0x18734861c 0x18740a26c 0x1005a4df0 0x1005af854 0x1005a8120 0x1005b175c 0x1005b2f18 0x19746d2e4 0x19746cfa8) 2015-06-20 14:44:41.646 UserLoginAndRegistration[6064:750474] *** Assertion failure in -[UIKeyboardTaskQueue waitUntilAllTasksAreFinished], /SourceCache/UIKit/UIKit-3318.16.14/Keyboard/UIKeyboardTaskQueue.m:374 2015-06-20 14:44:41.657 UserLoginAndRegistration[6064:750474] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '- [UIKeyboardTaskQueue waitUntilAllTasksAreFinished] may only be called from the main thread.' *** First throw call stack: (0x186551e48 0x196c4c0e4 0x186551d08 0x1873d5554 0x18ad2b0a8 0x18ad2b734 0x18ad24a1c 0x18b251564 0x18b0156a8 0x18b0169e4 0x18b0188dc 0x18adee0b4 0x100028f9c 0x10002b500 0x10002b5f4 0x10002b624 0x10002b68c 0x185ee6540 0x187407508 0x187358c94 0x18734861c 0x18740a26c 0x1005a4df0 0x1005af854 0x1005a8120 0x1005b175c 0x1005b2f18 0x19746d2e4 0x19746cfa8) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb) 
+8
function lldb swift xcode6 error-handling
source share
3 answers

You should always update user interface elements from the main queue, sometimes it works when you do not, but in most cases when you have strange behavior in your application, you are lucky that the compiler warns you, sometimes it takes time to find errors when things just don't work.

Use the code below to trigger and reject your alerts.

 dispatch_async(dispatch_get_main_queue()) { self.dismissViewControllerAnimated(true, completion: nil) } dispatch_async(dispatch_get_main_queue()) { self.displayMyAlertMessage("Wrong name or password") } 

You can learn more about this at the Central Dispatch Service (GCD) Link.

+12
source share

You must first cancel your warnings first. Use this code below.

Works with Swift 3

 DispatchQueue.main.async { your code goes here } 
+3
source share

You must queue your process to execute it.

You can refer to the example below, how I was able to resolve it in my scenario when I had the same problem.

 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) //Above line was generating same exception in my scenario // I got it resolved by using NSOperationQueue.mainQueue().addOperationWithBlock { } 
0
source share

All Articles