Facebook Developers
DocsToolsSupportNewsApps
Log In
  • Social Plugins
  • Facebook Login
  • Open Graph
  • Facebook APIs
  • Games
  • Payments
  • App Center
  • Promote Your App
  • iOS
  • Android
  • JavaScript
  • PHP
  • More SDKs
  • Topics
    • Facebook SDK for iOS
  • Authentication
    • Facebook Login with iOS
    • iOS 6 Integration
    • Understanding Sessions
    • Handling App Links
  • Data Access
    • Fetch User Data
    • Run FQL Queries
  • Sharing & Distribution
    • Sharing on iOS
    • Publish to Feed
    • iOS Share Sheet
    • Feed Dialog
    • Link To Your Native App
    • Send Requests
    • Setup for App Center
  • Customization
    • Add Search to Friend Selector
    • Manage Your Own Token Cache
    • Share an App ID Across Apps
  • Optimization
    • Batch Requests
    • Caching
    • Select Friends by Device
    • Handling Errors

Publish to Feed

Documentation › Publish to Feed

The Facebook SDK for iOS provides a way to publish to a user's timeline with the Graph API. This is an alternate to using the Feed Dialog to publish a story. You can also use this method to update a user's status.

The Facebook SDK's FBRequestConnection class has a convenience class method you can use to publish to a user's timeline: startWithGraphPath:parameters:HTTPMethod:completionHandler:. Pass USER_ID/feed to the Graph API path parameter, pass in the desired feed parameters and set ''POST'' as the HTTP method.

This document walks through the following:

  • Prerequisites
  • Sample Overview
  • Step 1: Set Up the Share View Trigger
  • Step 2: Set Up the Share View
  • Step 3: Present the Share View
  • Step 4: Publish the Story
  • Troubleshooting
  • Additional Info

Note: To see an example of using the SDK to make the API call, skip to the Publish the Story section.


Prerequisites

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.


Sample Overview

The completed sample allows users to log in with Facebook and publish a link on their timeline.

The implementation builds on top of Facebook Login, adding a button that opens up a view where the user can share a pre-defined link. The share view shows a preview of the post and a text field where the user can enter an optional message. When the user taps on the share button, a story is published to their timeline and an alert pops up with the story's ID.

The sample contains a main view controller that displays the initial view. You'll add a second view controller for the share preview. The share view controller is presented modally. When the user taps a share button, the story is published in the share view controller. Then, a confirmation alert displays. When the user dismisses the alert, the share view controller closes.


Step 1: Set Up the Share View Trigger

In this step, you'll add a button in the initial view controller. When the user clicks the button, the share view displays.

Make the following changes in your main view controller's nib file:

  • Add a Round Rect Button object to the view. Set the button title to ''Publish''.
  • Hide the ''Publish'' button initially. You only want to display the button after the user authenticates.
  • Add an action to the ''Publish'' button and attach it to your main view controller's implementation file. Name the action ''publishButtonAction''.
  • Add an outlet for the ''Publish'' button to your view controller's implementation file so that it's private. Name the outlet ''publishButton''.

When you've completed these steps, your implementation file should have the defined outlet and an empty publishButtonAction: 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 publish button only when the user is authenticated:

- (void)sessionStateChanged:(NSNotification*)notification {
    if (FBSession.activeSession.isOpen) {
        self.publishButton.hidden = NO;
        [self.authButton setTitle:@"Logout" forState:UIControlStateNormal];
    } else {
        self.publishButton.hidden = YES;
        [self.authButton setTitle:@"Login" forState:UIControlStateNormal];
    }
}

Step 2: Set Up the Share View

This step sets up the share preview display. The story information is hard-coded for simplicity. At the end of this step, the display can be linked to the main view controller. You'll set up publishing in a later step.

Step 2a: Create the UI

First, add a new view controller for the share view display. From the Xcode File menu select New > File, select the Objective-C class template, name the class ShareViewController, make it a subclass of UIViewController and select the ''With XIB for user interface'' option.

Open up the ShareViewController nib file and add the UI components for the story preview and share. You'll add components for the published story's image, name, caption and description. You'll also add a text input field for a user message. Finally, you'll add a toolbar with two buttons, one to cancel and a second to publish the story.

Toolbar:

  • Add a Toolbar object to the top of the view.
  • The initial Bar Button Item object represents the cancel button. Set the title to ''Cancel''.
  • Add an action to the ''Cancel'' button and attach it to your main view controller's implementation file. Name the action ''cancelButtonAction''.
  • Add a Flexible Space Bar Button Item object to the toolbar and place it to the right of the ''Cancel'' button. This ensures the button you add next appears on the right of the toolbar.
  • Add a Bar Button Item object to the toolbar and place it to the right of the space button. This represents the share button. Set the title to ''Share''.
  • Add an action to the ''Share'' button and attach it to your main view controller's implementation file. Name the action ''shareButtonAction''.

Message:

  • Add a Text View object to the view below the toolbar. Stretch it out to take up most of the view's width.
  • In the Connections Inspector, connect the delegate outlet to the File's Owner.
  • Add an outlet to your view controller's implementation file so it's private. Name the outlet ''postMessageTextView''.
  • (Optional): To add a text input border effect, add a ''View'' object just above the text view. Set its size to be slightly bigger than the text view and then set the background color to black.

Image:

  • Add an Image View object to the view below the ''Message'' text view, to the left of the main view.
  • In the Attributes Inspector, set the View > Mode to Aspect Fit.
  • In the Size Inspector, set the width to 80 and the height to 80.
  • Add an outlet to your view controller's implementation file so it's private. Name the outlet ''postImageView''.

Name:

  • Add a Label object to the view. Place it to the right of the ''Image'' image view and below the ''Message'' text view.
  • In the Attributes Inspector, set the text color to a dark blue and the font to System Bold.
  • Add an outlet to your view controller's implementation file so it's private. Name the outlet ''postNameLabel''.

Caption:

  • Add a Label object to the view. Place it below the ''Name'' label.
  • In the Attributes Inspector, set the text color to a dark gray and the make the font size smaller than the ''Name'' label. Set the Lines attribute to 0.
  • Add an outlet to your view controller's implementation file so it's private. Name the outlet ''postCaptionLabel''.

Description:

  • Add a Label object to the view. Place it below the ''Caption'' label.
  • In the Attributes Inspector, set the font size to be smaller than the ''Name'' label font size. Set the Lines attribute to 0.
  • Add an outlet to your view controller's implementation file so it's private. Name the outlet ''postDescriptionLabel''.

When you've added the UI components, you're nib should look like this:


Step 2b: Configure the Message UI

In this step, you'll add logic to control the message UI. The message UI is implemented with a UITextView. You'll add logic to show the placeholder text when appropriate. You'll also add logic to dismiss the text input whenever the user taps outside the input field.

Open up the ShareViewController implementation file and list UITextViewDelegate as one of the protocols the class conforms to, so you can respond when the user start or stops editing text:

@interface ShareViewController ()
<UITextViewDelegate>

Next, define a constant string for the placeholder text by adding the following code before the class interface declaration:

NSString *const kPlaceholderPostMessage = @"Say something about this...";

Next, add a private helper method, which you'll use to set the placeholder message:

- (void)resetPostMessage
{
    self.postMessageTextView.text = kPlaceholderPostMessage;
    self.postMessageTextView.textColor = [UIColor lightGrayColor];
}

Then, implement UITextViewDelegate methods that handle text input editing changes. You'll clear the placeholder text whenever editing begins. You'll set the placeholder text when editing is done and the input text is empty:

- (void)textViewDidBeginEditing:(UITextView *)textView
{
    // Clear the message text when the user starts editing
    if ([textView.text isEqualToString:kPlaceholderPostMessage]) {
        textView.text = @"";
        textView.textColor = [UIColor blackColor];
    }
}

- (void)textViewDidEndEditing:(UITextView *)textView
{
    // Reset to placeholder text if the user is done
    // editing and no message has been entered.
    if ([textView.text isEqualToString:@""]) {
        [self resetPostMessage];
    }
}

Next, add logic to detect if a user taps outside the text view. When this is detected, you'll close the keyboard:

/*
 * 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];
    }
}

Step 2c: Configure the Display Data

In this step, you'll configure the information displayed in the share preview. You'll define a new property that holds this data in an NSMutableDictionary object. You'll use the same property later on when making the API call to publish the story.

First, define the new property to hold the display data:

@property (strong, nonatomic) NSMutableDictionary *postParams;

Synthesize this new property:

@synthesize postParams = _postParams;

Set the display data value in the view controller's initWithNibName:bundle: method by adding the following code to the custom initialization section:

self.postParams =
        [[NSMutableDictionary alloc] initWithObjectsAndKeys:
         @"https://developers.facebook.com/ios", @"link",
         @"https://developers.facebook.com/attachment/iossdk_logo.png", @"picture",
         @"Facebook SDK for iOS", @"name",
         @"Build great social apps and get more installs.", @"caption",
         @"The Facebook SDK for iOS makes it easier and faster to develop Facebook integrated iOS apps.", @"description",
         nil];

Pass the display data to the share view UI components by adding this code to the end of the viewDidLoad method:

// Show placeholder text
[self resetPostMessage];
// Set up the post information, hard-coded for this sample
self.postNameLabel.text = [self.postParams objectForKey:@"name"];
self.postCaptionLabel.text = [self.postParams
                              objectForKey:@"caption"];
[self.postCaptionLabel sizeToFit];
self.postDescriptionLabel.text = [self.postParams
                                  objectForKey:@"description"];
[self.postDescriptionLabel sizeToFit];

Step 2d: Load the Story Image

In this step, you'll set up the story's image display. You'll load the image data asynchronously to ensure the share view display isn't blocked while the image is fetched.

First, define properties to hold the image data and the image connection request:

@property (strong, nonatomic) NSMutableData *imageData;
@property (strong, nonatomic) NSURLConnection *imageConnection;

Synthesize these new properties:

@synthesize imageData = _imageData;
@synthesize imageConnection = _imageConnection;

In the viewDidLoad method, start the image request by adding this code to the end of the method:

// Kick off loading of image data asynchronously so as not
// to block the UI.
self.imageData = [[NSMutableData alloc] init];
NSURLRequest *imageRequest = [NSURLRequest
                              requestWithURL:
                              [NSURL URLWithString:
                               [self.postParams objectForKey:@"picture"]]];
self.imageConnection = [[NSURLConnection alloc] initWithRequest:
                               imageRequest delegate:self];

Next, cancel any active connections by adding this code to the end of the viewDidUnload method:

if (self.imageConnection) {
    [self.imageConnection cancel];
    self.imageConnection = nil;
}

Finally, implement the NSURLConnection delegate methods to handle the incoming request data. You'll load the preview image when the image data is successfully retrieved:

- (void)connection:(NSURLConnection*)connection
    didReceiveData:(NSData*)data{
    [self.imageData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
    // Load the image
    self.postImageView.image = [UIImage imageWithData:
                                [NSData dataWithData:self.imageData]];
    self.imageConnection = nil;
    self.imageData = nil;
}

- (void)connection:(NSURLConnection *)connection
  didFailWithError:(NSError *)error{
    self.imageConnection = nil;
    self.imageData = nil;
}

Step 2e: Configure the Cancel Action

In this step, you'll implement the cancel action.

First, fill out the cancelButtonAction: method to dismiss the share view when the user taps the ''Cancel'' button:

- (IBAction)cancelButtonAction:(id)sender {
    [[self presentingViewController]
     dismissModalViewControllerAnimated:YES];
}

Step 3: Present the Share View

In this step, you'll set up the logic that presents the share view when the publish button is tapped in the main view.

Open the main view controller and import the ShareViewController class, so you can initialize and present it:

#import "ShareViewController.h"

Next, fill out the publishButtonAction: implementation to initialize and present the share view controller:

- (IBAction)publishButtonAction:(id)sender {
    ShareViewController *viewController = [[ShareViewController alloc]
                                           initWithNibName:@"ShareViewController"
                                           bundle:nil];
    [self presentViewController:viewController animated:YES completion:nil];
}

Build and run the project to make sure it runs without errors. Once authenticated, tap ''Publish'' and verify that the share preview UI looks good. Make any necessary adjustments to the UI components. Test that the message input placeholder text is shown and cleared correctly. Tap outside the message to make sure the keyboard closes. Finally, verify that tapping the cancel button dismisses the share view.


Step 4: Publish the Story

In this final step, you'll add logic to publish the story. Before publishing the story you'll check if the user had previously granted you publish_actions permissions and if not, you'll request this permission.

Open up the ShareViewController implementation file and import the Facebook SDK so you can make the publish request:

#import <FacebookSDK/FacebookSDK.h>

Next, add a helper method that will publish the story:

- (void)publishStory
{
    [FBRequestConnection
     startWithGraphPath:@"me/feed"
     parameters:self.postParams
     HTTPMethod:@"POST"
     completionHandler:^(FBRequestConnection *connection,
                         id result,
                         NSError *error) {
         NSString *alertText;
         if (error) {
             alertText = [NSString stringWithFormat:
                          @"error: domain = %@, code = %d",
                          error.domain, error.code];
         } else {
             alertText = [NSString stringWithFormat:
                          @"Posted action, id: %@",
                          [result objectForKey:@"id"]];
         }
         // Show the result in an alert
         [[[UIAlertView alloc] initWithTitle:@"Result"
                                     message:alertText
                                    delegate:self
                           cancelButtonTitle:@"OK!"
                           otherButtonTitles:nil]
          show];
     }];
}

Next, fill out the shareButtonAction: method to ask for publish the story after checking if you have been granted publish_actions permissions for the user on this device:

- (IBAction)shareButtonAction:(id)sender {
    // Hide keyboard if showing when button clicked
    if ([self.postMessageTextView isFirstResponder]) {
        [self.postMessageTextView resignFirstResponder];
    }
    // Add user message parameter if user filled it in
    if (![self.postMessageTextView.text
          isEqualToString:kPlaceholderPostMessage] &&
        ![self.postMessageTextView.text isEqualToString:@""]) {
        [self.postParams setObject:self.postMessageTextView.text
                            forKey:@"message"];
    }

    // 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, publish the story
                [self publishStory];
            }
        }];
    } else {
        // If permissions present, publish the story
        [self publishStory];
    }
}

An alert appears after the story is published whether the request succeeds or fails. When the alert is dismissed, you'll dismiss the share view controller. To respond to the alert being dismissed, first add UIAlertViewDelegate to the list of protocols the ShareViewController class conforms to.

Next, implement the UIAlertView delegate method that is notified when the alert is dismissed and dismiss the share view:

- (void) alertView:(UIAlertView *)alertView
didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    [[self presentingViewController]
     dismissModalViewControllerAnimated:YES];
}

Build and run the project to make sure it runs without errors. Once authenticated, tap ''Publish''. Then, on the share view, enter a message and tap ''Share''. You should see the permissions dialog or permissions alert (iOS6+) asking for publish permissions. If you allow publish permissions you should see an alert confirming that the story published. Check your timeline to verify the story published correctly.

Feel free to modify the code and test your own links in the published story.


Troubleshooting

The Graph API Explorer provides a way for you to debug any Graph API issues you're seeing. If you're having problems publishing a story, try it with the Graph API Explorer, as it may give you more error into and help you out.


Additional Info

  • FBRequestConnection: reference for the connection request class.
  • JustRequestSample: sample included in the SDK that shows how to use Facebook request classes.
Updated 4 hours ago
Facebook © 2013 · English (US)
AboutAdvertisingCareersPlatform PoliciesPrivacy Policy