I started to use Facebook SDK for iOS and i'm a little bit confused,
I'm seeing this little piece of code that shows how we can perform a batch request however having a completion handler per request is absurd for me. how can you make a completion handler per request when you make a single batch request ? maybe i didn't get the concept ? there is for sure an explanation for this but i don't see it right now
if ([[FBSDKAccessToken currentAccessToken] hasGranted:@"user_likes"]) {
FBSDKGraphRequest *requestMe = [[FBSDKGraphRequest alloc]
initWithGraphPath:@"me" parameters:nil];
FBSDKGraphRequest *requestLikes = [[FBSDKGraphRequest alloc]
initWithGraphPath:@"me/likes" parameters:nil];
FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init];
[connection addRequest:requestMe
completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
//TODO: process me information
}];
[connection addRequest:requestLikes
completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
//TODO: process like information
}];
[connection start];
}
If it is the only way to do it how can i know when all my requests have been performed ?
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];
}