KPM KPM - 16 days ago 14
Swift Question

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?

Answer

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 >: MultiplicationPrecedence

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.