In Swift how to call method with parameters on GCD main thread?

In my app I have a function that makes an NSRURLSession and sends out an NSURLRequest using

sesh.dataTaskWithRequest(req, completionHandler: {(data, response, error)

In the completion block for this task, I need to do some computation that adds a UIImage to the calling viewcontroller. I have a func called

  • Parsing Excel Data in Apple Swift
  • How to parse JSON using Alamofire in Swift 3.0 without any third-party library
  • how to create instance of a class from a string in swift 3
  • Adding Image Transition Animation in Swift
  • Saving a Dictionary of key-values in Firebase using Swift
  • Image within PFFile will be uploaded to parse instead of being saved into the local datastorage
  • func displayQRCode(receiveAddr, withAmountInBTC:amountBTC)
    

    that does the UIImage-adding computation. If I try to run the view-adding code inside of the completion block, Xcode throws an error saying that I can’t use the layout engine while in a background process. So I found some code on SO that tries to queue a method on the main thread:

    let time = dispatch_time(DISPATCH_TIME_NOW, Int64(0.0 * Double(NSEC_PER_MSEC)))
                        dispatch_after(time, dispatch_get_main_queue(), {
                            let returned = UIApplication.sharedApplication().sendAction("displayQRCode:", to: self.delegate, from: self, forEvent: nil)
                            })
    

    However, I don’t know how to add the parameters “receiveAddr” and “amountBTC” to this function call. How would I do this, or can someone suggest an optimal way for adding a method call to the application’s main queue?

    7 Solutions Collect From Internet About “In Swift how to call method with parameters on GCD main thread?”

    Just write this in completion handler.No need to use dispatch_after

     dispatch_async(dispatch_get_main_queue(),{
    
        let delegateObj = UIApplication.sharedApplication().delegate as YourAppDelegateClass
        delegateObj.addUIImage("yourstring")
    
     })
    

    Swift 3:

    DispatchQueue.main.async { 
            let delegateObj = UIApplication.sharedApplication().delegate as YourAppDelegateClass
            delegateObj.addUIImage("yourstring")
    }
    

    Also for dispatch after on main queue

    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
        // your code here
    }
    

    Replace YourAppDelegateClass with you delegate class

    Swift 3 version:

    DispatchQueue.main.async {
        print("Hello")
    }
    

    Swift 2

    Using Trailing Closures this becomes:

    dispatch_async(dispatch_get_main_queue()) {
        self.tableView.reloadData()
    }
    

    Trailing Closures is Swift syntactic sugar that enables defining the closure outside of the function parameter scope. For more information see Trailing Closures in Swift 2.2 Programming Language Guide.

    In dispatch_async case the API is func dispatch_async(queue: dispatch_queue_t, _ block: dispatch_block_t) since dispatch_block_t is type alias for () -> Void – A closure that receives 0 parameters and does not have a return value, and block being the last parameter of the function we can define the closure in the outer scope of dispatch_async.

    Here’s the nicer (IMO) Swifty/Cocoa style syntax to achieve the same result as the other answers:

    NSOperationQueue.mainQueue().addOperationWithBlock({
        // Your code here
    })
    

    Or you could grab the popular Async Swift library for even less code and more functionality:

    Async.main {
        // Your code here
    }
    

    The proper way to do this is to use dispatch_async in the main_queue, as I did in the following code

    dispatch_async(dispatch_get_main_queue(), {
                            (self.delegate as TBGQRCodeViewController).displayQRCode(receiveAddr, withAmountInBTC:amountBTC)
                            })
    

    Don’t forget to weakify self if you are using self inside of the closure.

    dispatch_async(dispatch_get_main_queue(),{ [weak self] () -> () in
                if let strongSelf = self {
                    self?.doSomething()
                }
            })
    

    Here’s a nice little global function you can add for a nicer syntax:

    func dispatch_on_main(block: dispatch_block_t) {
        dispatch_async(dispatch_get_main_queue(), block)
    }
    

    And usage

    dispatch_on_main {
        // Do some UI stuff
    }