Suppose you have a network method that only uses a single block callback
typedef void (^Handler)(BOOL success, id response, NSError *error);
- (void)makeRequestWithHandler:(Handler)handler;
But you have to make this request dozens of times, and you want to reuse the same failure handler in most cases? Easy, just have a factory function that returns a block:
typedef void (^SuccessHandler)(id response);
typedef void (^ErrorHandler)(NSError *error);
Handler makeHandler(SuccessHandler successBlock, ErrorHandler errorBlock)
{
return ^(BOOL success, id response, NSError *error)
{
if (success)
{
if (successBlock) successBlock(response);
}
else
{
if (errorBlock) errorBlock(error);
}
}
}
Now you can elegantly call your singler-handler function with seperate success/failure handlers whenever you feel like it:
[[MyNetworkClass sharedInstance] makeRequestWithHandler:makeHandler(^(id response) {
//success code
}, ^(NSError *error) {
//error code
})];
This also means that if you have a generic error handler, you can just change the error condition in your makeHandler function to:
if (errorBlock) errorBlock(error); else //generic error handling behaviour
And then to use this fallback, just call your network method as follows:
[[MyNetworkClass sharedInstance] makeRequestWithHandler:makeHandler(^(id response) {
//success code
}, NULL)];
And this makeHandler method could even be built into the network library, with various standard implementations for your convenience.
So having a single callback gives you huge flexibility. Having seprate success/failure handlers built into the network method interface would force you to always specify two parameters; there's no easy way to make an equivalent factory function that takes a single handler block and splits it into two.
@kylef those solutions take advantage of the fact that AFNetworking's request operation is a leaky abstraction of NSOperation. My gist makes no reference to AFNetworking. Another network library that didn't use NSOperation but still used the two-handler approach wouldn't neccesarily allow that solution.
Also, If I'm making a lot of requests, having to do that isn't very DRY. I could wrap all the request methods of the library with new methods that take a single handler of course, but if users have to do that, it rather defeats the point of designing a nice API in the first place.