I created an FBBatchHandler class to automatically combine results and return a single completion handler to the caller. Source and example usage below. It's currently designed specifically for retrieving events (i.e. the final result is an NSArray of events), but it should be easily to repurpose it for other tasks. Let me know if this works for you.
FBBatchHandler.h
#import <Foundation/Foundation.h>
#import "FBSDKGraphRequestConnection.h"
typedef void (^BatchFinishedHandler)(NSArray *result, NSError *error);
@interface FBBatchHandler : NSObject
- (instancetype)initWithConnection:(FBSDKGraphRequestConnection *)connection
finishedHandler:(BatchFinishedHandler)finishHandler;
- (void)addRequestResult:(id)result;
@end
FBBatchHandler.m
#import "FBBatchHandler.h"
@interface FBBatchHandler () <FBSDKGraphRequestConnectionDelegate>
@property (nonatomic, strong) FBSDKGraphRequestConnection *connection;
@property (nonatomic, strong) BatchFinishedHandler finishHandler;
@property (nonatomic, strong) NSMutableArray *batchResults;
@end
@implementation FBBatchHandler
#pragma mark - Instance
- (instancetype)initWithConnection:(FBSDKGraphRequestConnection *)connection
finishedHandler:(BatchFinishedHandler)finishHandler {
if (self = [super init]) {
_connection = connection;
_connection.delegate = self;
_finishHandler = finishHandler;
_batchResults = [NSMutableArray new];
}
return self;
}
#pragma mark - Public methods
- (void)addRequestResult:(id)result {
if ([result isKindOfClass:[NSDictionary class]]) {
[self.batchResults addObjectsFromArray:result[@"data"]];
}
}
#pragma mark - FBSDKGraphRequestConnectionDelegate
- (void)requestConnectionDidFinishLoading:(FBSDKGraphRequestConnection *)connection {
self.finishHandler([self.batchResults copy], nil);
}
- (void)requestConnection:(FBSDKGraphRequestConnection *)connection
didFailWithError:(NSError *)error {
self.finishHandler([self.batchResults copy], error);
}
@end
Example Usage
- (void)retrieveEvents {
NSDictionary *params = @{@"since": @"now", @"fields": @"id,name,description,start_time,end_time,location,picture"};
FBSDKGraphRequest *attending = [[FBSDKGraphRequest alloc] initWithGraphPath:@"/me/events/attending" parameters:params];
FBSDKGraphRequest *created = [[FBSDKGraphRequest alloc] initWithGraphPath:@"/me/events/created" parameters:params];
FBSDKGraphRequest *maybe = [[FBSDKGraphRequest alloc] initWithGraphPath:@"/me/events/maybe" parameters:params];
FBSDKGraphRequest *notReplied = [[FBSDKGraphRequest alloc] initWithGraphPath:@"/me/events/not_replied" parameters:params];
FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init];
FBBatchHandler *batchHandler = [[FBBatchHandler alloc] initWithConnection:connection
finishedHandler:^(NSArray *result, NSError *error) {
// Here's the "single" completion handler
}];
[connection addRequest:attending
completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
[batchHandler addRequestResult:result];
}];
[connection addRequest:created
completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
[batchHandler addRequestResult:result];
}];
[connection addRequest:maybe
completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
[batchHandler addRequestResult:result];
}];
[connection addRequest:notReplied
completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
[batchHandler addRequestResult:result];
}];
[connection start];
}