The Graph API supports batching of requests, so you can specify multiple requests in a single HTTP request. It's more efficient to batch your requests rather than making several individual ones.
The Facebook SDK for iOS supports batching through the FBRequestConnection and FBRequest classes. To make batched requests through the Facebook SDK, create FBRequest objects describing each operation you'd like to perform and add each them a FBRequestConnection instance. The final step involves calling the start method on the FBRequestConnection instance to connect to the server. Each FBRequest can include a callback to process the server response.
This document walks through the following:
Before you begin, make sure you already set up Facebook Login. This ensures you have the prerequisites and your app is ready for additional Facebook integration.
The completed sample allows users to log in with Facebook, view their most recent status and post a new one. When updating the user's status, a batch request is made to update the status and display it.
The implementation builds on top of Facebook Login, adding a text area for entering a status update, a button for posting the status and a label that displays it.

In this step, you'll add UI components to show the latest status and post a new one.
Open the main nib file and add UI components representing the status text input, submit button and most recent status.
Status Text View:
Text View object to the view.Post Button
Round Rect Button object to the view. Set the button title to ''Post''.Status Label:
Label object to the view below the other components.When you've completed these steps, your implementation file should have the three defined outlets and an empty postButtonAction: action method.
If you followed the Facebook Login doc, you should have a sessionStateChanged: method defined in your view controller implementation file that controls the logged-in and logged-out UI. Modify this method to show the UI components only when the user is authenticated:
- (void)sessionStateChanged:(NSNotification*)notification {
if (FBSession.activeSession.isOpen) {
[self.authButton setTitle:@"Logout" forState:UIControlStateNormal];
self.postButton.hidden = NO;
self.postMessageTextView.hidden = NO;
self.statusLabel.hidden = NO;
} else {
[self.authButton setTitle:@"Login" forState:UIControlStateNormal];
self.postButton.hidden = YES;
self.postMessageTextView.hidden = YES;
self.statusLabel.hidden = YES;
}
}
Finally, add logic to close the keyboard when a user taps outside the text view:
/*
* A simple way to dismiss the message text view:
* whenever the user clicks outside the view.
*/
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *) event
{
UITouch *touch = [[event allTouches] anyObject];
if ([self.postMessageTextView isFirstResponder] &&
(self.postMessageTextView != touch.view))
{
[self.postMessageTextView resignFirstResponder];
}
}
In this step, you'll configure your app to ask for permissions it needs to read the latest status. To read the initial and the updated status, you'll ask for the read_stream permission. You'll add logic to ask for permission to post a status when you add the code around the post button. This will ensure that you are asking for publish permissions in context, i.e. when the post button is clicked.
If you followed the Facebook Login doc, you should have a openSessionWithAllowLoginUI: method defined in your app delegate implementation file. Open the app delegate implementation file and modify the FBSession initialization section to request the additional permission:
- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI {
NSArray *permissions = [[NSArray alloc] initWithObjects:
@"read_stream", nil];
return [FBSession openActiveSessionWithPermissions:permissions
allowLoginUI:allowLoginUI
completionHandler:^(FBSession *session,
FBSessionState state,
NSError *error) {
[self sessionStateChanged:session
state:state
error:error];
}];
}
Build and run the project to make sure it runs without errors. Tap the ''Login'' button to log in with Facebook. During the authentication step, you should see a dialog asking for publish permissions and a second one asking for News Feed access permissions, which is an extended permission. Once authenticated, the status update UI should display. Tapping the ''Post'' button won't work yet; the most recent status info should be empty as you haven't added logic to retrieve it.
In this step, you'll get the most recent status when the user authenticates. The me/statuses Graph API endpoint provides a list of user statuses. Get the most recent status by making a Graph API request to this endpoint with the parameter limit=1. Call the FBRequestConnection class method, startWithGraphPath:completionHandler: with the me/statuses endpoint to get the status info. Then update the status display and in the completion handler.
Add the status retrieval code to the sessionStateChanged: method. You'll add this to the end of the if clause where the user session is open:
// Get the most recent status
[FBRequestConnection
startWithGraphPath:@"me/statuses?limit=1"
completionHandler:^(FBRequestConnection *connection,
id result,
NSError *error) {
if (!error) {
// Set the status label
self.statusLabel.text = [[[result objectForKey:@"data"]
objectAtIndex:0]
objectForKey:@"message"];
}
}];
Build and run the project to make sure it runs without errors. Once authenticated, verify that the status label contains your most recent status update.
In this step, you'll make a batch request when the user clicks the ''Post'' button. Before you make the request you'll check if the user had previously granted your app the publish_actions permission to enable your app to post an updated status. If the permission has not been granted for the user on this device, you'll ask for that first.
The batch request consists of two operations. The first is a POST operation to the me/feed endpoint with a message parameter to update the user's status. The second operation is a GET request to the Facebook object ID that's retrieved from the post operation. The second operation is dependent on the first. To set up this dependency, when the first request is added to the FBRequestConnection connection instance, the addRequest:completionHandler:batchEntryName: method is used.
The specified batch entry name is then used in constructing the second request:
FBRequest *request2 = [FBRequest requestForGraphPath:
@"{result=status-post:$.id}"];
To make the batch request, first add a helper method to do this. You'll call this method in the post button logic:
- (void) updateStatus
{
FBRequestConnection *connection = [[FBRequestConnection alloc] init];
// First request posts a status update
NSDictionary *request1Params = [[NSDictionary alloc]
initWithObjectsAndKeys:
self.postMessageTextView.text, @"message",
nil];
FBRequest *request1 =
[FBRequest requestWithGraphPath:@"me/feed"
parameters:request1Params
HTTPMethod:@"POST"];
[connection addRequest:request1
completionHandler:
^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
}
}
batchEntryName:@"status-post"
];
// Second request retrieves the status posted
FBRequest *request2 = [FBRequest requestForGraphPath:
@"{result=status-post:$.id}"];
[connection addRequest:request2
completionHandler:
^(FBRequestConnection *connection, id result, NSError *error) {
if (!error && result) {
self.statusLabel.text = [result objectForKey:@"message"];
}
// Clear text input.
self.postMessageTextView.text = @"";
}
];
[connection start];
}
Next, fill out the postButtonAction: method to check for the publish_actions permission and then call the updateStatus method you defined to make the batch request:
- (IBAction)postButtonAction:(id)sender {
if (![self.postMessageTextView.text isEqualToString:@""]) {
// Ask for publish_actions permissions in context
if ([FBSession.activeSession.permissions
indexOfObject:@"publish_actions"] == NSNotFound) {
// No permissions found in session, ask for it
[FBSession.activeSession
requestNewPublishPermissions:
[NSArray arrayWithObject:@"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session, NSError *error) {
if (!error) {
// If permissions granted, update the status
[self updateStatus];
}
}];
} else {
// If permissions present, update the status
[self updateStatus];
}
}
}
Build and run the project to make sure it runs without errors. Once authenticated, enter a new status and click ''Post''. You should see a permissions dialog or alert the first time you run this. Granting permissions will allow the status update to go through. Verify the updated status appears in the status label.
If you have any issues with your own batch requests, turn on debugging for the requests. To do this, add the following code before any requests:
[FBSettings setLoggingBehavior:[NSSet setWithObjects:
FBLoggingBehaviorFBRequests,
nil]];
You'll be able to debug any issues by viewing requests and responses from the servers.
If you get empty data back, your app hasn't requested the proper permissions. In this sample, you're displaying the user's status. If read_stream permissions are not requested, or if the user revoked or denied this permission, no data will be returned.
Scrumptious: sample included in the SDK that shows a batch request for a photo upload.