Switch views based on the result of a task with a quick

I am using NSURLSession to query the server. To do this, I create an NSURLSessionTask using a custom finalizerHandler.

Depending on the result, I want to switch to a different view. However, when I do this inside the completion handler, it doesn't work. The application crashes with the following error:

NSInternalInconsistencyException

      

The complete error is described as follows:

*** Assertion failure in -[UIKeyboardTaskQueue waitUntilAllTasksAreFinished], /SourceCache/UIKit_Sim/UIKit-3302.3.1/Keyboard/UIKeyboardTaskQueue.m:374

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] may only be called from the main thread.'

      

Note: I am using the following code to change opinions

let vc: AnyObject! = self.storyboard?.instantiateViewControllerWithIdentifier(viewID)
self.showViewController(vc as UIViewController, sender: vc)

      

What's wrong here?

+3


source to share


2 answers


The main problem is that your error message says "... can only be called from the main thread". So you are presumably calling this code from a background thread (maybe a completion block for a network request or something). Therefore, you need to send this code back to the main queue:

dispatch_async(dispatch_get_main_queue()) {
    let vc = self.storyboard.instantiateViewControllerWithIdentifier(viewID) as UIViewController
    showViewController(vc, sender: self)
}

      



Note. This code snippet makes several minor, unrelated changes, namely:

  • There is no point in specifying the destination view controller as its own sender. Usually you use the current view controller or some UIKit control like sender

    .

    I pointed out self

    how sender

    because let's assume you did it in your source controller. Or, if it was in IBAction

    for a button, perhaps you would have used the parameter sender

    for IBAction

    and not for the source view controller.

  • I would have lost my ghost AnyObject

    . I know the compiler probably suggested it to you, but that doesn't help legibility. I would suggest translating it directly to UIViewController

    .

+10


source


Anything you do that affects the UI should be done on the main thread, not in the completion handler. So, inside the call completion handler, call the performSelectorOnMainThread function, or use one of the other mechanisms that allows you to place this call on the main thread.



+1


source







All Articles