Best way to deal with lots of nested closures in Swift

I have some external SDK library that makes IO calls (either networking or database) in the form of blocks, like so:

SomeClass.doWork(success: {}, failure: {})

Now I need to chain about 60 different calls because we are working on data replication where each operation is distinct enough that it’s not the same, but the principle is there -> all of these take a success and a failure blocks.

What is the best way to organise this spaghetti:

let failureBlock: () -> Void = { // something
}

SomeClass.doWork(success: { [unowned self] in
   self.runChecks(success: {
       SomeOtherClass.somethingElse(success: { 
           SomeClass.doWork(success: { [unowned self] in
              self.doMore() ///... and on and on she goes
           }, failure: failureBlock)
       }, failure: failureBlock)
    }, failure: failureBlock)
}, failure: failureBlock)

Go to Source
Author: zaitsman