swiftfunctional-programmingdispatch-asynccompletionhandler

Syntax to wrap a completion handler in dispatch async


I have a completion handler that I need to assign to a property, but I want it to execute asynchronously.

If I didn't have that requirement, I would write:

request.completionBlock = completionBlock

But since I have this requirement, I have to write this

request.completionBlock = { response, error in
  DispatchQueue.main.async {
    completionBlock(response, error)
  }
}

which seems redundant and un-swifty.

Isn't there some easier syntax? I would like to write something like

request.completionBlock = completionBlock.map(DispatchQueue.main.async)

Can I express my need in such a simple way?


Solution

  • There isn't a built-in syntax for expressing that, but you can always define a generic function or operator to enable something along those lines.

    For example:

    infix operator >
    
    func ><T>(left:@escaping (T)->(), right:DispatchQueue) -> (T)->() {
      return { input in
        right.async { left(input) }
      }
    }
    

    With the above custom operator defined, your code can be:

    request.completionBlock = completionBlock > DispatchQueue.main
    

    which I think is the general feel you are looking for.