However, this is rather fragile, as it will not gives us any information about the error in question. In Swift 1.0, when such a structure presented itself, people usually implemented a Result type which can be either the result of the computation, or the error :

enum ResultType { case Success(r: NSDictionary) case Error(e: ErrorType) }

Given this enum, we can then change the code as follows:

func asynchronousWork(completion: (r: ResultType) -> Void) -> Void { NSURLConnection.sendAsynchronousRequest(request, queue: queue) { (response, data, error) -> Void in guard let data = data else { return } do { let result = try NSJSONSerialization.JSONObjectWithData(data, options: []) as! NSDictionary completion(r: ResultType.Success(r: result)) } catch let error { completion(r: ResultType.Error(e: error)) } } } // Call asynchronousWork { (r: ResultType) -> Void in switch r { case .Success(let e): print(e) case .Error(let e): print("Error", e) } }

Much nicer. When we look closely, though, there is a bit of overhead. We have to define a ResultType enum and encapsulate our data in it. What's more, if Result enums were the way Apple intends things to be, surely we would have one in the standard library.

Instead, we do have try / catch, a construct which is incompatible with the task at hand because you can't catch something that happens at some point in the future. I.e:

func asynchronousWork(completion: (r: ResultType) -> Void) throws -> Void { }

This can't throw, because the function returns before the computation has even begun.