This document refers to the iOS SDK v3. For the new iOS SDK v4 please see our new iOS docs.

Upgrading from 3.22 to 3.23

No special steps are required to upgrade to 3.23.

Upgrading from 3.21 to 3.22

No special steps are required to upgrade to 3.22.

Upgrading from 3.20 to 3.21

No special steps are required to upgrade to 3.21.

Upgrading from 3.19 to 3.20

v3.20 of the SDK targets v2.2 of the Graph API. No additional steps are required to upgrade to 3.20.

Upgrading from 3.18 to 3.19

No special steps are required to upgrade to 3.19.

Upgrading from 3.17 to 3.18

No special steps are required to upgrade to 3.18.

Upgrading from 3.17 to 3.17.1

No special steps are required to upgrade to 3.17.1.

If you would like your app to start reporting events for App Links Analytics, please use [BFURL URLWithInboundURL:url] to determine the incoming URL to handle within application:openURL:sourceApplication:annotation:. See App Links Analytics for more information.

Upgrading from 3.16 to 3.17

v3.17 of the SDK targets v2.1 of the Graph API. Any graph API calls your app makes may require updates.

No additional steps are required to upgrade to 3.17.

Upgrading from 3.15 to 3.16

No special steps are required to upgrade to 3.16.

The deprecated [FBSettings publishInstall:] has been deleted. Use [FBAppEvents activateApp] instead.

Upgrading from 3.14 to 3.15

No special steps are required to upgrade to 3.15.

Upgrading from 3.13 to 3.14

The Facebook SDK 3.14 for iOS upgrade brings significant new features such as the Message Dialog and the New Facebook Login and targets v2.0 of the Graph API. The new features are highlighted in the changelog. This document will cover important changes when upgrading.

The New Facebook Login

The New Facebook Login gives people control of the data they share with apps. Complete details can be found in the platform changelog and platform upgrade guide. here are the highlights:

  • Developers asking for more than public_profile, email, and user_friends will need to submit their apps for review by Facebook to approve the permissions the app will request. See the Permissions Guide for details. Existing apps have one year before they are required to go through review, including updates to existing apps. Apps created after April 30th, 2014 must go through review.
  • When requesting permissions (including at time of login), people can now decline individual permissions requested.
  • Several new methods have been added to help with this new flow:
MethodDescription

[FBSession hasGranted:]

Convenience helper to check for a granted permission.

[FBSession declinedPermissions]

Returns array of declined permissions.

[FBSession refreshPermissionsWithCompletionHandler:]

Explicitly refresh the permissions state from the server with an optional callback

  • To highlight these new features of the Facebook Login, a new tooltip UI element, FBLoginTooltipView was added. This is automatically used by FBLoginView but you may use the tooltip component explicitly with your own login flows. See their doc blocks for details and configuration options.
  • The New Facebook Login does not apply to iOS device account authentication.
  • The default login behavior has changed from FBSessionLoginBehaviorUseSystemAccountIfPresent to FBSessionLoginBehaviorWithFallbackToWebView.
  • Previously, basic_info was a permission you had to ask for and implied public_profile and user_friends together. With the New Facebook Login basic_info is now deprecated and should not be requested. Instead, ask for public_profile and user_friends (if needed) explicitly.

Graph API v2.0

  • All FBRequests target v2.0 of the Graph API. Individual FBRequests can be overridden via the - overrideVersionPartWith: selector.
  • See the platform changelog docs for changes in existing APIs, and new APIs. Two important changes are:

    • me/friends will only return friends that also use the app. See the new Invitable Friends API and Taggable Friends API for alternatives.
    • User IDs are now scoped to the calling app and can't be used in other apps.
  • You can still make calls to v1.0 graph API endpoints, and get the old Facebook Login by calling [FBSettings enablePlatformCompatibility:] but this will disable features that require v2.0 such as the FBLikeControl.

Bolts.framework

To use FBAppLinkResolver and take advantage of App Links, the Facebook SDK for iOS requires the Bolts framework. The Bolts.framework is installed alongside the Facebook SDK by the package installer (default location is ~/Documents/Bolts.framework).

Upgrading from 3.12 to 3.13

No special steps are required to upgrade to 3.13.

Upgrading from 3.11 to 3.12

No special steps are required to upgrade to 3.12.

Upgrading from 3.10 to 3.11

The Facebook SDK 3.11 for iOS is a minor update that adds stability fixes. Please note one of the fixes was to correct the type of the ref property on the FBAppLinkData class from NSArray to NSString.

You can read the Changelog to see a detailed list of changes. To upgrade from SDK 3.10 to SDK 3.11, no additional steps are required other than updating the framework binary.

Upgrading from 3.9 to 3.10

The Facebook SDK 3.10 for iOS is a minor update that adds stability fixes, the ability to set the loginBehavior of (FBLoginView), and the ability to pre-select a person's friends via the selection property of (FBFriendPickerViewController) .

You can read the changelog to see a detailed list of changes. To upgrade from SDK 3.9 to SDK 3.10, no additional steps are required other than updating the framework binary.

Upgrading from 3.8 to 3.9

The Facebook SDK 3.9 for iOS is a minor update that adds stability fixes and the ability to set a state change handler to (FBSession).

You can read the changelog to see a detailed list of changes. To upgrade from SDK 3.8 to SDK 3.9, no additional steps are required other than updating the framework binary.

This update also takes the (FBAppEvents) API out of beta.

Upgrading from 3.7 to 3.8

The Facebook SDK 3.8 for iOS is a minor update that adds Xcode 5 and iOS 7 support, stability fixes, automatic permissions refresh and the ability to specify batch request parameters to (FBRequestConnection).

This version also supports 64 bit applications and can be linked to by applications that target the arm64 architecture.

You can read the changelog to see a detailed list of changes. To upgrade from SDK 3.7 to SDK 3.8, no additional steps are required other than updating the framework binary.

Since iOS 7 is a significant update to iOS, you should consider reviewing Apple's transition guides (may require login):

Upgrading from 3.6 to 3.7

The Facebook SDK 3.7 for iOS is a minor update that adds automatic error handling, stability fixes, and updates the logo and text on the login button (FBLoginView) for better conversion.

You can read the changelog to see a detailed list of changes. To upgrade from SDK 3.6 to SDK 3.7, no additional steps are required other than updating the framework binary.

Important: If you are using the FBLoginView control, you should take care to verify its layout in your app since the default text is wider than in 3.6 and previous versions. You can override the text via localization - see the Scrumptious sample to see how.

Upgrading from 3.5 to 3.6

The Facebook SDK 3.6 is a minor update that makes the SDK easier to setup and adds support for using App Events.

You can read the changelog to see a detailed list of changes. To upgrade from SDK 3.5 to SDK 3.6:

  1. Remove the framework dependencies added to your app when you installed the Facebook SDK. The SDK still depends on them but now loads them automatically making setup simpler. Remove these frameworks / libraries:

    • Accounts.framework
    • AdSupport.framework
    • Security.framework
    • Social.framework
    • libsqlite3.dylib [or remove the -lsqlite3.0 linker flag]

    [Note: if your app uses any of the APIs from those frameworks / libraries directly, your project should still include the framework explicitly]

  2. Remove the FacebookSDKResources.bundle. Images and strings from this resource bundle are included automatically.

    [Note: this automatic loading does not make your app larger. Xcode will omit them from a built version of your app if your app doesn't use them.]

Upgrading from 3.2 to 3.5

The Facebook SDK 3.5 for iOS upgrade brings significant new features for using the native Share Dialog, calling the new Open Graph APIs for creating objects, staging images for user-owned objects, and handling cross-app calls.

You can read what's new to see a high level list of changes and view the changelog for further details. Jump to the reference table for a quick view of the API differences.

To upgrade from SDK 3.2 to SDK 3.5:

Add the Security.framework

To secure the channel used to make / receive cross-app calls between your app and the Facebook app, Facebook SDK 3.5 now requires that apps include the Security.framework. Remember, iOS includes these frameworks by default, so adding this framework does not increase the size of your app.

Add FacebookDisplayName to the .plist

Facebook SDK 3.5 requires that developers set the Facebook app name in the app's .plist under the key FacebookDisplayName. The value of this key must be an exact match to the value of the Display Name field under Settings in the Facebook devapp.

Setup an app to use native Share Dialog and Login Dialog

Two major features of Facebook SDK 3.5 are support for the native Share Dialog and Login Dialog included in version 3.x of the Facebook app. You can easily configure your app to use these features using these simple steps:

  • Include several frameworks Accounts, AdSupport, Security, Social, sqlite3.0.dylib
  • Update your .plist with a FacebookAppID, FacebookDisplayName, and URL Type
  • In your app delegate, override the openURL call:
- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {

    BOOL wasHandled = [FBAppCall handleOpenURL:url
                             sourceApplication:sourceApplication];

    // add app-specific handling code here
    return wasHandled;
}
  • Request basic_info permissions when making an initial connection to Facebook, ex:
...
[FBSession openActiveSessionWithReadPermissions:@[@"basic_info", @"email"]
                                   allowLoginUI:YES
                              completionHandler:^(FBSession *session,
                                                  FBSessionState status,
                                                  NSError *error) {
                                  // Respond to session state changes, 
                                  // ex: updating the view
                              }];
...

Once these steps are complete, you can open and receive responses for native dialogs. For example, to publish an Open Graph read action for Snow Crash, use:

    NSDictionary* object = @{
                             @"fbsdk:create_object": @YES,
                             @"type": @"books.book",
                             @"title": @"Snow Crash",
                             @"url": @"https://apps.notrepro.net/fbsdktoolkit/objects/books/Snow-Crash.html",
                             @"image": @"http://en.wikipedia.org/wiki/File:Snowcrash.jpg",
                             @"data": @{@"isbn": @"0553380958"}
                             };

    id<FBOpenGraphAction> action = (id<FBOpenGraphAction>)[FBGraphObject graphObject];
    [action setObject:object forKey:@"book"];

    [FBDialogs presentShareDialogWithOpenGraphAction:action
                                          actionType:@"books.reads"
                                 previewPropertyName:@"book"
                                             handler:^(FBAppCall *call, NSDictionary *results, NSError *error) {
                                                 if(error) {
                                                     NSLog(@"Error: %@", error.description);
                                                 } else {
                                                     NSLog(@"Success!");
                                                 }
                                             }];

Use FBAppCall

FBAppCall is a new class that helps your app respond to cross-app calls from the Facebook app. Such calls are made when:

  1. returning to your app after displaying the Share Dialog
  2. people click on deep links in News Feed stories
  3. returning to your app after completing a call to Facebook Login

For more information, see Using FBAppCall.

Update Facebook Dialog Calls

The FBNativeDialogs class is deprecated in favor of FBDialogs, which provides support for opening the Share Dialog along with the iOS 6 Share Sheet. To update to the new class, make these changes:

  1. change calls from [FBNativeDialogs presentShareDialogModallyFrom] to [FBDialogs presentOSIntegratedShareDialogModallyFrom]
  2. change calls from [FBNativeDialogs canPresentShareDialogWithSession] to [FBDialogs canPresentOSIntegratedShareDialogWithSession]
  3. change handlers from FBShareDialogHandler to FBOSIntegratedShareDialogHandler

Update any FBSBJSON usage

The FBSBJSON headers are no longer included with the Facebook SDK. Switch to using a different serializer, ex: the NSJSONSerialization class.

Upgrading from 3.1 to 3.2

The Facebook SDK 3.2 for iOS upgrade brings better error handling support, access token importing, a new webview dialog class replacing the deprecated Facebook dialog APIs, and numerous bug fixes.

You can view the changelog for further details. Jump to the reference table for a quick view of the API differences.

Upgrading your app:

Make API changes

This is the mapping of API calls in v3.1 versus v3.2 of the Facebook SDK:

v3.1v3.2

reauthorizeWithPublishPermissions: defaultAudience:completionHandler:

requestNewPublishPermissions: defaultAudience:completionHandler:

reauthorizeWithReadPermissions: completionHandler:

requestNewReadPermissions:completionHandler:

accessToken property of an FBSession instance

accessTokenData property of an FBSession instance returns an FBAccessTokenData object. Then get the accessToken property of the FBAccessTokenData object

expirationDate property of an FBSession instance

accessTokenData property of an FBSession instance returns an FBAccessTokenData object. Then get the expirationDate property of the FBAccessTokenData object

loginType property of an FBSession instance

accessTokenData property of an FBSession instance returns an FBAccessTokenData object. Then get the loginType property of the FBAccessTokenData object

dialog:* methods on a Facebook instance and FBDialogDelegate protocol methods

present* class methods of FBWebDialogs and handler implementation

Use the table above to map your API calls when upgrading to v3.2 of the Facebook SDK. Upgrading the Facebook Dialogs is a little more involved as you also need to migrate any previous delegate callbacks. The Facebook Dialog upgrade is discussed further in the next section.

Update your Facebook Dialog calls

Facebook Dialogs were supported in v3.1 of the SDK using APIs that were included for backward compatibility. This required you to include a DeprecatedHeaders folder into your project. To invoke the dialog you then made a call to the dialog method of an instance of the Facebook object, passing in any additional required parameters. In v3.2 of the SDK a new class, FBWebDialogs has been introduced. You no longer need to include the deprecated headers. Instead, you use class methods in the FBWebDialogs to display the dialogs.

To help you migrate your code, you'll see v3.1 sample code and the corresponding code migrated to v3.2.

Requests Dialog

The code sample below shows v3.1 of the SDK being used to display the Requests dialog and handle the callback response:

#import "Facebook.h"
...
@interface ViewController () (FBDialogDelegate>
@end
...
/**
 * Helper method for parsing URL parameters.
 */
- (NSDictionary*)parseURLParams:(NSString *)query {
    NSArray *pairs = [query componentsSeparatedByString:@"&"];
    NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
    for (NSString *pair in pairs) {
        NSArray *kv = [pair componentsSeparatedByString:@"="];
        NSString *val =
        [[kv objectAtIndex:1]
         stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

        [params setObject:val forKey:[kv objectAtIndex:0]];
    }
    return params;
}

/**
 * Method that displays the Requests dialog.
 */
- (void)sendRequest {
    NSMutableDictionary* params =
    [NSMutableDictionary dictionaryWithObjectsAndKeys:
     @"Learn how to make your iOS apps social.", @"message",
     nil];

    [self.facebook dialog:@"apprequests"
                andParams:params
              andDelegate:self];
}

/**
 * FBDialogDelegate method: Handling error
 */
- (void)dialog:(FBDialog*)dialog didFailWithError:(NSError *)error {
    // Case A: Error launching the dialog or sending request.
    NSLog(@"Error sending request.")
}

/**
 * FBDialogDelegate method: Handling dialog "x" cancel
 */
- (void) dialogDidNotCompleteWithUrl:(NSURL *)url {
    // Case B: Person clicked the "x" icon
    NSLog(@"Person canceled request.");
}

/**
 * FBDialogDelegate method: Handling dialog send/cancel
 */
- (void)dialogCompleteWithUrl:(NSURL *)url {
    // Case C: Dialog shown and the person clicks Cancel or Send
    NSDictionary *urlParams = [self parseURLParams:[url query]];
    if (![urlParams valueForKey:@"request"]) {
        // Person clicked the Cancel button
        NSLog(@"Person canceled request.");
    } else {
        NSString *requestID = [urlParams valueForKey:@"request"];
        NSLog(@"Request ID: %@", requestID);
    }
}

After migration to v3.2 of the SDK, the corresponding code looks like this:

- (void)sendRequest:(NSArray *) targeted {    
    // Display the requests dialog
    [FBWebDialogs
     presentRequestsDialogModallyWithSession:nil
     message:@"Learn how to make your iOS apps social."
     title:nil
     parameters:nil
     handler:^(FBWebDialogResult result, NSURL *resultURL, NSError *error) {
         if (error) {
             // Case A: Error launching the dialog or sending request.
             NSLog(@"Error sending request.");
         } else {
             if (result == FBWebDialogResultDialogNotCompleted) {
                 // Case B: Person clicked the "x" icon
                 NSLog(@"Person canceled request.");
             } else {
                 // Case C: Dialog shown and the person clicks Cancel or Send
                 NSDictionary *urlParams = [self parseURLParams:[resultURL query]];
                 if (![urlParams valueForKey:@"request"]) {
                     // Person clicked the Cancel button
                     NSLog(@"Person canceled request.");
                 } else {
                     // Person clicked the Send button
                     NSString *requestID = [urlParams valueForKey:@"request"];
                     NSLog(@"Request ID: %@", requestID);
                 }
             }
         }
     }];
}

You can use the presentRequestsDialogModallyWithSession:message:title:parameters:handler: class method to display the Requests dialog. In v3.1 of the SDK, the message was passed in to the andParams parameter of the dialog:andParams:andDelegate: method. In v3.2 of the SDK, the message is passed in to the message parameter. Take a look at comments marked with Case A, Case B and Case C to see how the delegate method implementation has been migrated to the v3.2 method handler.

If your v3.1 code passed in additional parameters, ex: a suggestions parameter to show a filtered list, you can pass this to the v3.2 code:

- (void)sendRequest:(NSArray *) targeted {
    // Suggested friends to show in dialog
    NSMutableDictionary* params = 
        @{@"suggestions" : @"286400088,100003086810435"};

    // Display the requests dialog
    [FBWebDialogs
     presentRequestsDialogModallyWithSession:nil
     message:@"Learn how to make your iOS apps social."
     title:nil
     parameters:params
     ...

The v3.1 Facebook dialog methods required you to include the deprecated Facebook headers. You no longer need to do this:

#import (del)"Facebook.h"(/del)<FacebookSDK/FacebookSDK.h>

Additionally, you no longer need to have your class conform to the FBDialogDelegate protocol:

@interface ViewController () (del)<FBDialogDelegate>(/del)

After making these changes, if you are not referencing any additional deprecated methods, you can now delete the DeprecatedHeaders folder from the Frameworks section of your Project Navigator.

Note: FBWebDialogs does not support enabling frictionless requests in v3.2. This support has been added in v3.2.1. Frictionless request support was set up in the v3.1 SDK as follows:

[self.facebook enableFrictionlessRequests];

If you need to use this feature in your app with v3.2, then you should upgrade to v3.2.1 or continue using the v3.1 SDK approach to invoke the Requests dialog.

Feed Dialog

The code sample below shows v3.1 of the SDK being used to display the Feed dialog and handle the callback response:

#import "Facebook.h"
...
@interface ViewController () (FBDialogDelegate>
@end
...
/**
 * Helper method for parsing URL parameters.
 */
- (NSDictionary*)parseURLParams:(NSString *)query {...}

/**
 * Method that displays the Feed dialog.
 */
- (void)showFeedDialog {
    // Put together the dialog parameters
    NSMutableDictionary *params =
    [NSMutableDictionary dictionaryWithObjectsAndKeys:
     @"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",
     @"https://developers.facebook.com/docs/ios", @"link",
     @"https://raw.github.com/fbsamples/ios-3.x-howtos/master/Images/iossdk_logo.png", @"picture",
     nil];

    // Invoke the dialog
    [self.facebook dialog:@"feed" andParams:params andDelegate:self];
}

/**
 * FBDialogDelegate method: Handling error
 */
- (void)dialog:(FBDialog*)dialog didFailWithError:(NSError *)error {
    // Case A: Error launching the dialog or publishing story.
    NSLog(@"Error publishing story.")
}

/**
 * FBDialogDelegate method: Handling dialog "x" cancel
 */
- (void) dialogDidNotCompleteWithUrl:(NSURL *)url {
    // Case B: Person clicked the "x" icon
    NSLog(@"Person canceled story publishing.");
}

/**
 * FBDialogDelegate method: Handling dialog send/cancel
 */
- (void)dialogCompleteWithUrl:(NSURL *)url {
    // Case C: Dialog shown and the person clicks Cancel or Share
    NSDictionary *urlParams = [self parseURLParams:[url query]];
    if (![urlParams valueForKey:@"post_id"]) {
        // Person clicked the Cancel button
        NSLog(@"Person canceled story publishing.");
    } else {
        // Person clicked the Share button
        NSString *postID = [urlParams valueForKey:@"post_id"];
        NSLog(@"Posted story, id: %@", postID);
    }
}

After migration to v3.2 of the SDK, the corresponding code looks like this:

/**
 * Method that displays the Feed dialog.
 */
- (void)showFeedDialog {
    // Put together the dialog parameters
    NSMutableDictionary *params =
    [NSMutableDictionary dictionaryWithObjectsAndKeys:
     @"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",
     @"https://developers.facebook.com/docs/ios", @"link",
     @"https://raw.github.com/fbsamples/ios-3.x-howtos/master/Images/iossdk_logo.png", @"picture",
     nil];

    // Invoke the dialog
    [FBWebDialogs presentFeedDialogModallyWithSession:nil
                                           parameters:params
                                              handler:
     ^(FBWebDialogResult result, NSURL *resultURL, NSError *error) {
         if (error) {
             // Case A: Error launching the dialog or publishing story.
             NSLog(@"Error publishing story.");
         } else {
             if (result == FBWebDialogResultDialogNotCompleted) {
                 // Case B: Person clicked the "x" icon
                 NSLog(@"Person canceled story publishing.");
             } else {
                 // Case C: Dialog shown and the person clicks Cancel or Share
                 NSDictionary *urlParams = [self parseURLParams:[resultURL query]];
                 if (![urlParams valueForKey:@"post_id"]) {
                     // Person clicked the Cancel button
                     NSLog(@"Person canceled story publishing.");
                 } else {
                     // Person clicked the Share button
                     NSString *postID = [urlParams valueForKey:@"post_id"];
                     NSLog(@"Posted story, id: %@", postID);
                 }
             }
         }
    }];
}

You can use the presentFeedDialogModallyWithSession:parameters:handler: class method to display the Feed dialog. Take a look at comments marked with Case A, Case B and Case C to see how the delegate method implementation has been migrated to the v3.2 method handler.

The v3.1 Facebook dialog methods required you to include the deprecated Facebook headers. You no longer need to do this:

#import (del)"Facebook.h"(/del)<FacebookSDK/FacebookSDK.h>

Additionally, you no longer need to have your class conform to the FBDialogDelegate protocol:

@interface ViewController () (del)<FBDialogDelegate>(/del)

After making these changes, if you are not referencing any additional deprecated methods, you can now delete the DeprecatedHeaders folder from the Frameworks section of your Project Navigator.


Add better error handling support

You can upgrade your app to take advantage of the enhanced error handling support introduced in v3.2 of the Facebook SDK. The NSError(FBError) category is introduced to provide properties to help you detect and handle Facebook-related errors. With the additional support you can now handle scenarios such as a person disallowing your app from accessing their Facebook account in iOS6 settings.

Refer to the error handling doc for more details on the best practices for handling errors.

Upgrading from 3.0 to 3.1

There are a few simple - yet important - changes between v3.0 and v3.1 of the Facebook SDK for iOS.

The main purpose of the upgrade is to bring compatibility with iOS v6.0 and its native Facebook support. Using v3.1 of the SDK means that your apps benefit greatly from that support when it is available, but that they automatically fall back to use the previous app-switching or web-based authentication flows on older versions of the operating system.

Additional Framework Dependencies

To benefit from this capability, apps built with v3.1 of the SDK will need to have three new framework dependencies added: 'Accounts', 'AdSupport' and 'Social'. To add these, go to the 'Linked Frameworks and Libraries' section of the project target's Summary pane, and click the 'plus' button to add them:

Note: You should use the 'Optional' flag for iOS6-specific frameworks if you would like your app to also build for older versions of the operating systems.

Once done, your Project Navigator should look something like this:

Asking for Read & Write Permissions Separately

You are now required to request read and publish permission separately (and in that order). Most likely, you will request the read permissions for personalization when the app starts and the person first logs in. Later, if appropriate, your app can request publish permissions when it intends to post data to Facebook.

You cannot request read and publish permissions simultaneously using iOS6's Facebook support, and if you attempt to, the SDK will take the person through a less-optimal app-switching or web-based authentication flow.

Asking for the two types separately also greatly improves the chances that people will grant the publish permissions, since your app will only seek them at the time it needs them, most likely when the person has a stronger intent.

Therefore, if your app previously used v3.0 of the SDK, you will need to remove usage of openActiveSessionWithPermissions:allowLoginUI:completionHandler: and replace it with openActiveSessionWithReadPermissions:allowLoginUI:completionHandler: (or even more simply, openActiveSessionWithAllowLoginUI).

Later, when your app needs to publish back to Facebook, you should use reauthorizeWithPublishPermissions:defaultAudience:completionHandler: to seek the additional permissions.

Similarly, you should update the deprecated reauthorizeWithPermissions:behavior:completionHandler: with its two replacements reauthorizeWithReadPermissions:completionHandler: and reauthorizeWithPublishPermissions:defaultAudience:completionHandler:.

It is important that you do not simply attempt to call the two individual methods back-to-back to replace either of the deprecated functions.

Changes in Handling Facebook Login Cancel Flow

In v3.0, to properly handle an interruption during the authorization flow ex: person clicking the device home button, you were instructed to add this code to your app delegate's applicationDidBecomeActive: method:

if (FBSession.activeSession.state == FBSessionStateCreatedOpening) {
    [FBSession.activeSession close];
}

In v3.1, remove this logic otherwise you'll see that person's logging in via iOS6 may show a login failure the very first time round. Instead replace the code with the following new method that has been defined in FBSession:

[FBSession.activeSession handleDidBecomeActive];

Upgrading from 2.0 to 3.1

The Facebook SDK 3.1 for iOS makes it easier to develop Facebook integrated apps, including better session management, pre-built UI views for common functions, improved Facebook API support, mobile install measurement and support for Facebook iOS6 integration.

You can jump to the feature comparison section for a list of feature difference between v2.0 and v3.1, or go to the reference table for a quick view of the API differences.

This guide walks you through the differences between v2.0 and v3.1 of the SDK and provides steps you can use to update your app.

Overview of changes:

How to upgrade your app:

New features you should consider:

Feature Comparison

Here's a matrix showing the feature comparison between v2.0 and v3.1 of the SDK:

Featurev2.0v3.1

iOS6 Native Login

iOS6 Native Share Sheet

Ad Analytics

Built-in support to shield against server-side breaking changes

Native UI component - Login Button, User Settings, Profile Picture

Native UI component - Friend Picker

Native UI component - Place Picker

Localization support for UI components

Support for blocks - session, API calls

Session management - automatic token storage and token refresh

Session management - state change notification support

Support for strongly typed common Facebook data, ex: user, place

Support for pre-fetching and caching friend picker data

Support for pre-fetching and caching place picker data

API support for batch requests

Facebook Login (App-switch to FB for iOS/Safari)

Dialog Support - Requests and Feed

Graph API Support

Session management - manual token refresh

Support for multiple iOS apps and single Facebook app ID

Support for linking into app from Facebook for iOS app

API Changes

Overview

In v2.0 of the SDK, your flow for integrating with Facebook was basically the following:

  1. Instantiate a Facebook object.
  2. Authenticate by calling a login method on the Facebook instance. Implement login delegate methods to process the results.
  3. Make API calls or invoke Feed or Requests Dialogs by calling the appropriate methods on the Facebook instance. Implement request delegate methods to process the results.
  4. Log out by calling a logout method on the Facebook instance.

In v3.1 of the SDK, several classes have been introduced to better separate out functionality. Instead of simply having a Facebook instance that all SDK-related calls flow through, v3.1 of the SDK has an FBSession class to handle session-related tasks, an FBRequest class for request-related functionality, an FBRequestConnection that represents a connection to service a request, and various other classes including those defining native UI controls. The flow you use to integrate with Facebook changes accordingly. For example, a basic flow could be the following:

  1. Instantiate an FBSession object.
  2. Authenticate by calling an open method on the FBSession instance. Implement completion handlers to process the results.
  3. Create an FBRequest object for an API call, passing in the FBSession object.
  4. Service the API request by creating an FBRequestConnection object, adding the FBRequest and starting the connection. Implement completion handlers to process the results.
  5. Log outuser by calling a close method on the FBSession instance.

The new SDK contains UI controls and convenience class methods that can simplify your integration flow. For example, if your app authenticatesuser then fetches the person's friend list, a simplified flow could be as follows:

  1. Add the FBLoginView to your view. This displays a login button. When the person clicks the button they are authenticated.
  2. Implement a delegate method when the person is authenticated. In the method, call the static startForMyFriendsWithCompletionHandler: method on the FBRequestConnection class to fetch friend data. Implement the completion handler to process the results.

Asking for read & write permissions separately

In v3.1 of the SDK, you are required to request read and publish permission separately (and in that order). Most likely, you will request the read permissions for personalization when the app starts and the person first logs in. Later, if appropriate, your app can request publish permissions when it intends to post data to Facebook.

You cannot request read and publish permissions simultaneously using iOS6's Facebook support, and if you attempt to, the SDK will take the person through a less optimal app-switching or web-based authentication flow.

Asking for the two types separately also greatly improves the chances that people will grant the publish permissions, since your app will seek them only at the time it needs them, when the person has already begun to interact with your app and most likely has a stronger intent to share.

How different tasks are handled in v2.0 and v3.1 of the SDK

Taskv2.0v3.1

Initialize

initWithAppId:* to create Facebook instance

init* to create FBSession instance.

Login

authorize:

open* on FBSession instance or openActiveSession* class methods.

Process incoming Facebook Login URL

handleOpenURL:

handleOpenURL: on FBSession instance.

Check if a user is logged in

isSessionValid

isOpen on FBSession instance.

Logout

logout:

closeAndClearTokenInformation on FBSession instance.

Refresh an access token

extendAccessTokenIfNeeded

The SDK refreshes session automatically on API calls.

Make an API call

requestWith*

Use FBRequest, FBRequestConnection methods.

Use the Feed dialog

FBDialog

FBDialog on Facebook instance.

Use the Requests dialog

FBDialog

FBDialog on Facebook instance.

Step 1: Update the SDK and Framework Dependencies

Installing the Facebook SDK

The Facebook SDK is now packaged as a framework. You can download v3.1 of the SDK from here and install the package. The default install location is ~/Documents/FacebookSDK.

Note: Developing with v3.1 of the SDK requires Xcode 4.5+.

Updating the Facebook SDK in your Xcode Project

Add the Facebook SDK for iOS Framework to your Xcode project by dragging the FacebookSDK.framework folder from the SDK installation folder into the Frameworks section of your Project Navigator.

Choose 'Create groups for any added folders' and deselect 'Copy items into destination group's folder (if needed)' to keep the reference to the SDK installation folder, rather than creating a copy.

Add the Facebook SDK for iOS resource bundle by dragging the FacebookSDKResources.bundle file from the FacebookSDK.framework/Resources folder into the Frameworks section of your Project Navigator.

As you did when copying the Framework, choose 'Create groups for any added folders' and deselect 'Copy items into destination group's folder (if needed)'

The SDK relies on three other frameworks (AdSupport, Accounts and Social) to use the Facebook features built into iOS6. To add these, go to the 'Linked Frameworks and Libraries' section of the target's Summary pane, and click the 'plus' button to add them:

Note: You should use the 'Optional' flag for iOS6-specific frameworks if you would like your app to also build for older versions of the operating systems.

Once done, your Project Navigator should look something like this:

Adding SQLite

Next you need to add the ''-lsqlite3.0'' SQL library to the list of build dependencies in the Build Settings pane:

Include the Facebook SDK

In your app's implementation and header files, include v3.1 of the Facebook SDK wherever you previously included v2.0 of the SDK, for example:

// Previous SDK, v2.0
#import "FBConnect.h"
// Added v3.1 of the SDK
#import (FacebookSDK/FacebookSDK.h>

When you've updated the SDK and its dependencies, remove references to v2.0 of the SDK.

Step 2: Update Facebook Login

From Facebook to FBSession

In v2.0 of the SDK, Facebook Login, session state management, and API calls were all handled through a single class: Facebook. The Facebook class is deprecated as of release v3.0 of the SDK. The majority of the functions it provided are now separated between the FBSession, FBSessionTokenCachingStrategy, FBRequest, and FBRequestConnection classes. This section takes you through the changes relating to Facebook Login. See the sessions doc for more details on how the v3.1 SDK manages sessions. Read the Facebook Login doc for step-by-step instructions on adding Login to your app using v3.1 of the SDK.

To update your app, first add your Facebook app ID in your application's main .plist file. Create a key called FacebookAppID with a string value, and add the app ID there:

Facebook Login is now handled through the FBSession class. To authenticate a person, open an active FBSession, for example:

(del)[self.facebook authorize:nil];(/del)
[FBSession openActiveSessionWithReadPermissions:nil
                                   allowLoginUI:YES
                              completionHandler:^(FBSession *session,
                                                  FBSessionState state,
                                                  NSError *error) {
                                  [self sessionStateChanged:session
                                                      state:state
                                                      error:error];
                              }];

The code requests the default permissions, forces a login UI to be shown to the person. The method call defines a completion handler that is invoked whenever the session state changes. An example completion handler you can use is defined here:

- (void)sessionStateChanged:(FBSession *)session 
                      state:(FBSessionState) state
                      error:(NSError *)error
{
    switch (state) {
        case FBSessionStateOpen: {
            // Handle the logged in scenario

            // You may wish to show a logged in view

            break;
        }
        case FBSessionStateClosed:
        case FBSessionStateClosedLoginFailed: {
            // Handle the logged out scenario

            // Close the active session            
            [FBSession.activeSession closeAndClearTokenInformation];

            // You may wish to show a logged out view

            break;
        }
        default:
            break;
    }

    if (error) {
        // Handle authentication errors
    }    
}

To handle the logged in scenario, move over any code you had written in v2.0's FBSessionDelegate method: fbDidLogin. Keep in mind that v3.1 of the SDK automatically stores the session so there's no need to move code related to storing and retrieving a cached session.

To handle the logged out scenario, move over any code you had written in v2.0's FBSessionDelegate method: fbDidLogout. Don't move over any code related to session caching management.

The v3.1 SDK allows you to track and respond to session changes through a completion handler that you define when you open a session. In the example above, the sessionStateChanged:state:error: method will be invoked whenever the session state changes. This includes state changes that occur during the initial login flow and any changes that are triggered elsewhere in your app. For example, if you have a logout button in a separate class that closes the session, then the handler is called when the person clicks that button.

If the login UI flow fast-app switches to Facebook for iOS or to mobile Safari, you need to handle the incoming URL back to your app to complete the flow. In v2.0 of the SDK, this was done by implementing the application:openURL:sourceApplication:annotation: method in your app delegate. You need to modify your code to call the handleOpenURL: method on the active session instead of on the Facebook instance:

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {
    <del>return [self.facebook handleOpenURL:url];</del>
    return [FBSession.activeSession handleOpenURL:url];
}

Remove any Facebook code you have in the deprecated application:handleOpenURL: app delegate method as v3.1 of the Facebook SDK only supports iOS versions 4.3+.

The flow back to your app may be interrupted (for ex: if the person clicks the Home button while authenticating via the Facebook for iOS app). If this happens, the Facebook SDK can take care of any cleanup that may include starting a fresh session. To enable this, in the applicationDidBecomeActive: delegate method call the active session's handleDidBecomeActive method:

[FBSession.activeSession handleDidBecomeActive];

You should also take care of closing the session if the app is about to terminate. Do this by adding the following code to the person applicationWillTerminate: app delegate method:

[FBSession.activeSession close];

In v2.0 of the SDK, you had to store the Facebook token data. This is no longer necessary with v3.1. Once the person is authenticated, the Facebook SDK automatically stores the token data. It also refreshes the token data as needed when follow-on authentication or Facebook API calls made using the SDK.

Instances of FBSession have a state machine corresponding to their lifecycle. Read the session lifecycle doc for more details on this to better understand the flow.

Once you've authenticated, an instance of the active session can be retrieved by calling the activeSession static method on the FBSession class. The pre-built UI controls ex: FBLoginView, FBFriendPickerViewController, use the activeSession to set the default session.

To log out with v3.1 of the SDK, use the following code:

(del)[self.facebook logout];(/del)
[FBSession.activeSession closeAndClearTokenInformation];

Finally, be sure to swap out any code that checks for an open session with the v3.1 counterpart, ex:

(del)if ([self.facebook isSessionValid]) {(/del)
if (FBSession.activeSession.isOpen) {

Importing 2.0 Tokens

You can import tokens you stored with v2.0 of the SDK. This allows for a seamless login experience for people upgrading to your v3.1 SDK-based app. This means that if the person was previously logged in, they won't have to go through the log in flow after they upgrade your app. To enable this, all you have to do is add code to pass the token from one SDK session management system to the other.

The FBSessionTokenCachingStrategy class in v3.1 of the SDK is responsible for managing cached session data. It has a cacheTokenInformation: method that you can use to pass in and store previously cached token data. Once you've stored the data, you can call an FBSession open method that automatically checks the cache before opening the login UI.

In this quick example, assume that in your v2.0 SDK integration you stored the access token in NSUserDefaults when the person was authenticated:

- (void)fbDidLogin {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:[facebook accessToken] forKey:@"FBAccessTokenKey"];
    [defaults setObject:[facebook expirationDate] forKey:@"FBExpirationDateKey"];
    [defaults synchronize];

}

The access token was stored in the ''FBAccessTokenKey'' key and the token expiration info in the ''FBExpirationDateKey'' key.

Add the cached token checking code wherever you initially check for a valid Facebook session, ex: in a viewDidLoad method for the initial view that shows your Facebook integrated code or in the app delegate method, application:didFinishLaunchingWithOptions: if you check the session at app launch.

Open up the relevant class and import the headers related to token caching:

#import (FacebookSDK/FBSessionTokenCachingStrategy.h>

Add the following code to import the v2.0 SDK token into your v3.1 SDK integration:

// Check if there is any saved token data
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:@"FBAccessTokenKey"] 
        && [defaults objectForKey:@"FBExpirationDateKey"]) {
    // Get the saved token data
    NSString *accessToken = [defaults objectForKey:@"FBAccessTokenKey"];
    NSDate *expirationDate = [defaults objectForKey:@"FBExpirationDateKey"];

    // Check expiration date later than now, i.e. don't open expired tokens
    NSDate *nowDate = [NSDate date];
    if (NSOrderedDescending == [expirationDate compare:nowDate]) {
        // Cache the token
        NSDictionary *tokenInfo = [NSDictionary dictionaryWithObjectsAndKeys:
                                   accessToken, FBTokenInformationTokenKey,
                                   expirationDate, FBTokenInformationExpirationDateKey,
                                   nowDate, FBTokenInformationRefreshDateKey,
                                   nil];
        FBSessionTokenCachingStrategy *tokenCachingStrategy = 
            [FBSessionTokenCachingStrategy defaultInstance];
        [tokenCachingStrategy cacheTokenInformation:tokenInfo];
        // Now open the session and the cached token should
        // be picked up, open with nil permissions because
        // what you send is checked against any cached permissions
        // to determine token validity.
        [FBSession openActiveSessionWithReadPermissions:nil
                                           allowLoginUI:NO
                                      completionHandler:^(FBSession *session,
                                                          FBSessionState state,
                                                          NSError *error) {
                                          [self sessionStateChanged:session
                                                              state:state
                                                              error:error];
                                      }];
    }
    // Delete saved token data
    [defaults removeObjectForKey:@"FBAccessTokenKey"];
    [defaults removeObjectForKey:@"FBExpirationDateKey"];
    [defaults synchronize];
}

Using Login UI controls

The FBLoginView and FBUserSettingsViewController classes provide pre-built UI controls that you can use to create and manage an FBSession instance.

The FBLoginView is a button that can log in or log out. You can add it to your view programmatically like this:

FBLoginView *loginview = [[FBLoginView alloc] init];
[self.view addSubview:loginview];

If you require only basic permissions, this is all the code you need before making API calls. If you need to request additional permissions, you can modify the code like this:

FBLoginView *loginview = 
    [[FBLoginView alloc] initWithReadPermissions:[NSArray arrayWithObjects:
        @"email",
        @"user_likes",
        nil]];
[self.view addSubview:loginview];

The button automatically manages the correct display text ("Log In"/"Log Out"). If you conform to the FBLoginViewDelegate protocol, you can implement methods to get notifications of changes in the session state. Implement the loginViewShowingLoggedInUser: delegate method to get notifications when the person is logged in, and the loginViewShowingLoggedOutUser: delegate method to get notifications when the user is logged out.

Step 3: Update your Facebook API calls

It's easier to make and process API calls with v3.1 of the SDK. It includes strongly typed representations of common Graph API objects, ex: the User object. This makes it easy to program against the social graph. The SDK also supports batching of SDK requests, leading to improved latency for Facebook API calls.

In v2.0, request methods were invoked on a Facebook instance to initiate a request, ex: the requestWithGraphPath:andDelegate: method was used to make a Graph API call. When an SDK request was invoked, you could specify a delegate class conforming to the FBRequestDelegate class that would handle callbacks. The delegate would then be notified of API error and completion events.

In v3.1, making an API call involves the following basic flow:

  • Create an FBRequest object describing the API request.
  • Make a single connection by creating an FBRequestConnection instance and adding your FBRequest object.
  • Starting the connection by calling the start method.

You may also batch multiple requests simply by adding more than one request to an FBRequestConnection object through the addRequest:completionHandler:batchEntryName: method.

The Facebook SDK provides several static convenience methods for common API calls. These include:

  • startForMeWithCompletionHandler: - retrieve a person's profile.
  • startForMyFriendsWithCompletionHandler: - retrieve a person's friend list.
  • startForPlacesSearchAtCoordinate:radiusInMeters:resultsLimit:searchText:completionHandler: - perform a search near a specified location.
  • startForPostStatusUpdate:completionHandler: - post a status to a person's timeline.
  • startForPostStatusUpdate:place:tags:completionHandler: - post a status to a person's timeline. Include optional place and friends to tag.
  • startForUploadPhoto:completionHandler: - upload a photo to your app's photo album.

Here's an example of a v2.0 API call:

- (void)apiGraphMe {

    NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                   @"name",  @"fields",
                                   nil];
    [self.facebook requestWithGraphPath:@"me" andParams:params andDelegate:self];
}

- (void)request:(FBRequest *)request didLoad:(id)result {
    // Update a label that shows a person's name
    self.welcomeLabel.text = 
        [NSString stringWithFormat:@"Welcome %@", 
            [result objectForKey:@"name"]];
}

After updating to v3.1, the API call would look like this:

- (void)apiGraphMe {
    [FBRequestConnection startForMeWithCompletionHandler:
     ^(FBRequestConnection *connection,
       NSDictionary(FBGraphUser> *user,
       NSError *error) {
         if (!error) {
             self.welcomeLabel.text = 
                 [NSString stringWithFormat:@"Welcome %@", user.name];
         }
    }];
}

Step 4: Update your Facebook Dialog calls

The Facebook Feed and Requests Dialogs are supported in v3.1 of the SDK through the same methods used in v2.0. These methods are included for backward compatibility. To invoke the dialog you make a call to the dialog method of an instance of the Facebook object. To you need to do the following:

  • Import the backward compatibility Facebook SDK headers.
  • Create a Facebook instance whenever the Facebook session is open and clear the instance when the session is closed.
  • Call the Facebook Dialog methods as you did in v2.0, using the created Facebook instance.

Note: Even though the dialog methods are provided via a deprecated class, you can continue to use these methods until the same functionality is ported over in a future SDK release.

Add the headers by dragging the DeprecatedHeaders folder from the FacebookSDK.framework/Versions/A/DeprecatedHeaders folder into the Frameworks section of your Project Navigator:

Choose 'Create groups for any added folders' and deselect 'Copy items into destination group's folder (if needed)'. This adds the headers as a reference.

In the class where you manage your Facebook sessions, replace the Facebook framework import with the Facebook header import:

(del)#import &lt;FacebookSDK/FacebookSDK.h>(/del)
#import "Facebook.h"

This allows you to make calls to the FBDialog classes. The Facebook.h header includes the $lt;FacebookSDK/FacebookSDK.h> header files.

Note: If you have any problems with Xcode recognizing the Facebook.h file, just close and reopen your Xcode project.

The Facebook Login update example included a method named sessionStateChanged: that was invoked whenever the session changed. Update this method to initialize the Facebook property whenever the session is open and set it to nil when the session closes:

- (void)sessionStateChanged:(FBSession *)session 
                      state:(FBSessionState) state
                      error:(NSError *)error
{
    switch (state) {
        case FBSessionStateOpen: {
            // Handle the logged in scenario

            // Initiate a Facebook instance and properties
            if (nil == self.facebook) {
                    self.facebook = [[Facebook alloc]
                                 initWithAppId:FBSession.activeSession.appID
                                   andDelegate:nil];

                    // Store the Facebook session information
                    self.facebook.accessToken = FBSession.activeSession.accessToken;
                    self.facebook.expirationDate = FBSession.activeSession.expirationDate;
             }

            // You may wish to show a logged in view

            break;
        }
        case FBSessionStateClosed:
        case FBSessionStateClosedLoginFailed: {
            // Handle the logged out scenario

            // Clear out the Facebook instance
            self.facebook = nil;

            // Close the active session            
            [FBSession.activeSession closeAndClearTokenInformation];

            // You may wish to show a logged out view

            break;
        }
        default:
            break;
    }

    if (error) {
        // Handle authentication errors
    }    
}

If you're managing session changes differently in your code, follow a similar approach to create or clear the Facebook instance whenever the person's session is open or closed.

The rest of your Facebook Dialog code remains the same as v2.0 of the SDK. For example, to invoke the Requests Dialog you would have code similar to this:

NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                               @"Check out this awesome app.",  @"message",
                               nil];

[self.facebook dialog:@"apprequests"
            andParams:params
          andDelegate:nil];

Using native views for choosing friends or places

The Facebook SDK provides pre-built native UI controls for picking Facebook friends or nearby locations within your app. You can present the UI controls modally or push the view controllers as part of a UINavigationController set up. The UI controls include delegate methods that you can implement to respond to errors, data loads, or person selection changes.

There are detailed tutorials on how to implement the Friend Picker and the Place Picker.

Using mobile app install ads

You can now promote your mobile app directly in people's news feeds using Facebook's mobile app install ads. You can advertise this way regardless of whether your app uses Facebook.

The SDK 3.1 features a method in the FBSettings class called publishInstall: that asynchronously pings an install event to Facebook when it's invoked. Include it in the applicationDidBecomeActive: method of your app delegate like this:

[FBSettings publishInstall:YOUR_APP_ID];
...

The FBSettings class internally handles tracking repeat calls to prevent multiple installs from the same device being published.

Once you have this line of code in your app, you can go to the App Dashboard to configure text and images for your ad.

A step-by-step walkthrough for setting up mobile app install ads is available here.