Unleash Your Inner App Developer Part 41: Logging In With Facebook

Do you have an idea for an app but lack the programming knowledge to begin building it? In this weekly blog series, I will take you, the beginner app developer, step by step through the process of creating apps for the iPhone, iPod touch, and iPad. Join me each week on this adventure and you will experience how much fun turning your app ideas into reality can be! This is part 41 of the series. If you are just getting started, check out the beginning of the series at this link.

These days, more and more iOS apps offer users the option of logging in with Facebook. If you want your app to go viral, this is a great first step. In fact, 80 percent of the top-grossing iOS apps use social media logins. As stated in the Facebook documentation:

iPhone Life
Discover your iPhone's hidden features
Get a daily tip (with screenshots and clear instructions) so you can master your iPhone in just one minute a day.

"One of the benefits of having people sign in to your app using Facebook is that they can grant permissions to your app so you can retrieve information or perform actions on Facebook on their behalf."

If the main actions users perform in your app are posted on Facebook, it's a great way for their Facebook friends to find out that your app exists, and some of the great things they can do within your app.

Step 1: Installing the Facebook SDK for iOS

There are several steps you need to take in order to get started integrating Facebook with your iOS apps. The first step is installing the Facebook SDK for iOS.

  1. Installing the Facebook SDK for iOS - This is your first step in the process. First, click on this link which downloads the Facebook SDK for iOS .pkg installer file to your Mac. After the file has finished downloading, double-click the .pkg file to launch the installer (Figure 1).
Facebook SDK Installer
Figure 1 - The Facebook SDK for iOS installer
  1. Click Continue to read the developer terms, and then click Continue again to display the Select a Destination panel of the installer. Click Continue again to navigate to the Standard Install panel. Click Install to install the Facebook SDK for iOS in the default location (your Documents folder).
  1. When the installation is complete, you will be taken to a panel that says "The Installation was completed successfully". You can click Close to exit the installer.

Step 2: Registering as a Facebook Developer

Your next step is to obtain an ID for your app from Facebook.

  1. Click on this link to navigate to the Facebook's Developer Registration page (Figure 2).
Facebook Developer Registration
Figure 2 - The Facebook Developer Registration page
  1. If haven't already registered as a Facebook developer, click the Register Now button, which prompts you to enter your Facebook password.
  1. Next, a dialog appears asking if you accept the Facebook Platform Policy. If you agree, click the switch to respond YES, and then click Next.
  1. This displays a Register as a Facebook Developer dialog (Figure 3). 
Register as Facebook developer
Figure 3 - Registering as a Facebook developer

You need to enter your phone number in order to receive a confirmation code from Facebook (the dialog states that your phone number will be added to your timeline, but will not be visible to your friends.) After entering your phone number either select Send as Text or Send Via Phone Call to retrieve your confirmation code. After you receive your confirmation code, enter it and then click Register.

  1. If your registration is successful, you will see the dialog shown in Figure 4. Click the Done button to proceed.
Successfully registered
Figure 4 - You are now a registered Facebook Developer!

This takes you to the Facebook App Dashboard (Figure 5).

The Facebook App dashboard
 

Step 3: Obtaining a Facebook App ID

After registering as a Facebook developer, now you're ready to obtain a Facebook App ID.

  1. In the Facebook App Dashboard, select Apps > Create a New App (Figure 6).
Create an app
Figure 6 - Create a New App
  1. In the Create a New App dialog (Figure 7), enter your app's Display Name, Namespace (an optional unique identifier for your app), choose a Category, and then click the Create App button.
Create a New App dialog
Figure 7 - The Create a New App dialog
  1. In the Security Check dialog you will be prompted to type the text that you see and click Submit. This displays your app and it's new ID in the App Dashboard (Figure 8).
New app in dashboard
Figure 8 - Your newly registered app in the Facebook App Dashboard

 

Step 4: Configuring Your Facebook App

Now you need to configure your Facebook app to support login from an iOS app.

  1. In the panel on the left side of the Facebook App Dashboard, select Settings to display the App Settings page (Figure 9).
App Settings web page
Figure 9 - The App Settings page

 

  1. Click the + Add Platform button to display the Select Platform dialog (Figure 10).
Select platform
Figure 10 - The Select Platform dialog

 

  1. Select iOS. This displays a new iOS panel beneath your app in the Facebook App Settings page (Figure 11).

Configure app for iOS
Figure 11- Configuring your app for iOS
  1. In the Bundle ID field, enter your app's bundle identifier, which you can find in the General pane of the Project Editor in Xcode (Figure 12). Also, click on the switch to set Single Sign On to YES (you can leave the iPhone/iPad Store ID fields empty for now.) Afterwards, click Save Changes.
Bundle identifier
Figure 12 - Your app's Bundle Identifier in the General pane of the Project Editor

 

Step 5: Configuring Your Xcode Project

Now you need to add the Facebook SDK for iOS to your project and configure your .plist file.

  1. In the Project Navigator, right-click the Frameworks group and select Add Files to "<Project Name>"... from the popup menu. 
  1. In the Add Files dialog, navigate to the folder that contains the Facebook SDK for iOS that you downloaded earlier (it's located in the Documents folder by default). Select FacebookSDK.framework, make sure the Copy items into your destination group's folder (if needed) check box is unchecked, the Create groups for any added folders option is selected, and then click Add.
Add Facebook SDK
Figure 13 - Add the Facebook SDK to your project.

 

This adds the FacebookSDK.framework under your the Frameworks group.

  1. In the Project Navigator, expand your project's Supporting Files group, and select your project's .plist file.
  1. Select the very first item (Information Property List) in the .plist file and click the plus sign that appears to the right (Figure 14). When you do this, a new item is added to the property list.
Add a plist entry
Figure 14 - Add a new item to the property list.
  1. In the popup for the new item under the Key column, enter the text FacebookAppID (Figure 15). Afterwards, double-click in the Value column and enter the app ID that was assigned to your app in the Facebook App Settings page.
Add the app id in the plist file
Figure 15 - Enter your app ID in the .plist file.

 

  1. Now you need to add another .plist entry. To do this, hover your mouse pointer over the Information Property List item (Figure 14) and click the plus sign again. In the Key column, enter FacebookDisplayName (Figure 16) and then press Tab. In the Value column, enter the Display Name you entered in the Facebook App Dashboard.
Add Display Name to plist file
Figure 16 - Add your app's Display Name to the .plist file.
  1. There's one more key you need to add to your .plist file. Hover your mouse pointer over the Information Property List item, and click the plus sign again. In the Key column, enter URL Types (Figure 17).
Add URL types to plist
Figure 17 - Add the URL types key to your project's .plist file
  1. Click the arrow to the left of URL types to expand the entry, and then click the arrow to the left of Item 0 to expand it. Change the Key below Item 0 to URL Schemes as shown in Figure 18.
Add URL Schemes to plist
Figure 18 - Set the Key to URL Schemes.
  1. Finally, click the arrow to the left of URL Schemes and set the Value of Item 0 to the app ID assigned to your app in the Facebook App Settings page, but with an fb prefix (Figure 19).
Set the Item 0 value
Figure 19 - Creating the URL Schemes entry in the .plist file

That's it! Now you need to write some code for your app that allows users to log in via Facebook.

Facebook Login Options

Facebook offers two options when logging into Facebook from your iOS app:

  1. Use the Facebook login view that displays a built-in Facebook login button and handles much of the complexity for logging in and out for you.
  2. Use your own custom login view and using API calls to the Facebook SDK.

The majority of apps need to use the second option, because not all users will want to log into your app using Facebook, and you will need to provide an alternative, such as an email address and password. So, in this post, I'll demonstrate how to implement your own custom login view.

Checking for an Active Facebook Session at Startup

If a user has already logged into your app via Facebook, you should check to see if there is still a valid session available, and if so, automatically log the user in. 

  1. At the top of your AppDelegate.h header file, add the following import statement:

     #import <FacebookSDK/FacebookSDK.h>

  1. In your AppDelegate.m implementation file, add the following code to the application:didFinishLaunchingWithOptions: method, before the final return YES; statement (note that you will get a compiler error until you complete the next steps):

    // Whenever a person opens the app, check for a cached session

    if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {

        

        // If there's one, just open the session silently, without showing the user the login UI

        [FBSession openActiveSessionWithReadPermissions:@[@"public_profile"]

                        allowLoginUI:NO

                        completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {

                        // Handler for session state changes

                        // This method will be called EACH time the session state changes,

                        // also for intermediate states and NOT just when the session open

                        [self sessionStateChanged:session state:state error:error];

                        }];

    }

When the AppDelegate's application:didFinishLaunchingWithOptions: method is executed at app startup, if the FBSession object's state is set to FBSessionStateCreatedTokenLoaded, this means there is an active Facebook session. If there is an active session, an openActiveSessionWithReadPermissions:allowLoginUI:completionHandler: message is sent to the FBSession object. Notice an @"public_profile" argument is passed in this message call. This requests access to the user's public profile. You must always pass this argument when creating this connection. You can also ask for additional permissions when making the connection. To find out more, check out Facebook's documentation at this link, under the section Asking for permissions.

The sequence diagram in Figure 20 shows the objects and message flow of the code you just added.

Check active session
Figure 20 - Checking for an active Facebook session at startup

Adding the Session State Handler Method

Now you need to add the sessionStateChanged: method you referenced in the code you added in the previous step along with a few helper methods.

  1. Add the following method declaration to your AppDelegate.h file:

- (void)sessionStateChanged:(FBSession *)session state:(FBSessionState) state error:(NSError *)error;

 
  1. Now add the following method implementations to your AppDelegate.m file:

// This method will handle ALL the session state changes in the app

- (void)sessionStateChanged:(FBSession *)session state:(FBSessionState) state error:(NSError *)error

{

    // If the session was opened successfully

    if (!error && state == FBSessionStateOpen){

        NSLog(@"Session opened");

        // Show the user the logged-in UI

        [self userLoggedIn];

        return;

    }

    if (state == FBSessionStateClosed || state == FBSessionStateClosedLoginFailed){

        // If the session is closed

        NSLog(@"Session closed");

        // Show the user the logged-out UI

        [self userLoggedOut];

    }

    

    // Handle errors

    if (error){

        NSLog(@"Error");

        NSString *alertText;

        NSString *alertTitle;

        // If the error requires people using an app to make an action outside of the app in order to recover

        if ([FBErrorUtility shouldNotifyUserForError:error] == YES){

            alertTitle = @"Something went wrong";

            alertText = [FBErrorUtility userMessageForError:error];

            [self showMessage:alertText withTitle:alertTitle];

        } else {

            

            // If the user cancelled login, do nothing

            if ([FBErrorUtility errorCategoryForError:error] == FBErrorCategoryUserCancelled) {

                NSLog(@"User cancelled login");

                

                // Handle session closures that happen outside of the app

            } else if ([FBErrorUtility errorCategoryForError:error] == FBErrorCategoryAuthenticationReopenSession){

                alertTitle = @"Session Error";

                alertText = @"Your current session is no longer valid. Please log in again.";

                [self showMessage:alertText withTitle:alertTitle];

                

                // Here we will handle all other errors with a generic error message.

                // We recommend you check our Handling Errors guide for more information

                // https://developers.facebook.com/docs/ios/errors/

            } else {

                //Get more error information from the error

                NSDictionary *errorInformation = [[[error.userInfo objectForKey:@"com.facebook.sdk:ParsedJSONResponseKey"] objectForKey:@"body"] objectForKey:@"error"];

                

                // Show the user an error message

                alertTitle = @"Something went wrong";

                alertText = [NSString stringWithFormat:@"Please retry. \n\n If the problem persists contact us and mention this error code: %@", [errorInformation objectForKey:@"message"]];

                [self showMessage:alertText withTitle:alertTitle];

            }

        }

        // Clear this token

        [FBSession.activeSession closeAndClearTokenInformation];

        // Show the user the logged-out UI

        [self userLoggedOut];

    }

}

 

- (void)userLoggedIn

{

    

}

 

- (void)userLoggedOut

{

    

}

 

- (void)showMessage:(NSString *)message withTitle:(NSString *)title

{

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];

    

    [alert show];

}

 

The sessionStateChanged: method is automatically called when there is any change in the status of the Facebook session. If the session state changes to open (FBSessionStateOpen), the userLoggedIn method is called. If you would like, you can add code to this method that changes a visual element to indicate the user is logged in, or you can perform some other action.

If the session state changes to closed (FBSessionStateClosed), the userLoggedOut method is called, where you can again add some code to respond to this change in state.

The rest of the code in the sessionStateChanged: method performs error handling and displays alerts to the user where appropriate.

    Figure 21 contains a sequence diagram that provides a visual representation of the objects and messages involved when the session state changes.
     
    Session State Changed sequence diagram
    Figure 21 - The session state changed sequence diagram

     

    Opening a New Facebook Session

    If there is no active Facebook session at startup, you need to create a new one. Typically, the code to create a new session is found in the action method for a "Log in with Facebook" button.

    1. Add the following code to your Facebook login button's action method (you can name your method differently than the method name shown here):

    - (IBAction)facebookButtonTouched:(id)sender {

     

        // Open a session showing the user the login UI

        // You must ALWAYS ask for public_profile permissions when opening a session

        [FBSession openActiveSessionWithReadPermissions:@[@"public_profile"]

                                            allowLoginUI:YES

                                          completionHandler:

            ^(FBSession *session, FBSessionState state, NSError *error) {

                 

                // Retrieve the app delegate

                AppDelegate* appDelegate = [UIApplication sharedApplication].delegate;

                // Call the app delegate's sessionStateChanged:state:error method to handle session state changes

                [appDelegate sessionStateChanged:session state:state error:error];

             }];

     

    }

    This code sends the FBSession object an openActiveSessionWithReadPermissions:allowLoginUI:completionHandler: message, again passing in the requested permissions (you can change the permissions to suit your needs). For the completionHandler argument, this code passes an Objective-C block that, when called, passes a sessionStateChanged:state:error: message to the AppDelegate object.

    If the Facebook app is installed on the user's iOS device, then control is passed to the app. Otherwise, control is passed to Facebook running in the iOS browser.

    1. During the Facebook login process, the Facebook app returns control to your application by calling the application:openURL:sourceApplication:annotation: method in your AppDelegate. So, you need to add this method to your AppDelegate.m file:

    // During the Facebook login flow, your app passes control to the Facebook iOS app or Facebook in a mobile browser.

    // After authentication, your app will be called back with the session information.

    - (BOOL)application:(UIApplication *)application

                openURL:(NSURL *)url

      sourceApplication:(NSString *)sourceApplication

             annotation:(id)annotation

    {

        return [FBAppCall handleOpenURL:url sourceApplication:sourceApplication];

    }

     

    Figure 22 contains a sequence diagram that depicts the object and message interaction during the login process.

    Logging In sequence diagram
    Figure 22 - The Facebook login sequence diagram
    1. Lastly, you need to add code that handles the case where the user leaves your app while the Facebook dialog is shown. Note that your AppDelegate.m file should already contain an applicationDidBecomeActive: method, so simply add the code shown below to the existing ethod.

    - (void)applicationDidBecomeActive:(UIApplication *)application

    {

        // Handle the user leaving the app while the Facebook login dialog is being shown

        // For example: when the user presses the iOS "home" button while the login dialog is active

        [FBAppCall handleDidBecomeActive];

    }

     

    Logging Out of Facebook

    Typically, your app will have a Log Out button (often in the Settings scene) that logs the user out of Facebook. It's good form to ask the user if they are sure they want to log out, so you should display an alert first, and then log out the user if they confirm.

    1. Select the header file of the view controller that contains the Log Out button, and adopt the UIActionSheetDelegate protocol:

    @interface SettingsTableViewController : mmUITableViewController <UIActionSheetDelegate>

     

    @end

    1. Next, select the implementation file of the view controller that contains the Log Out button, and add the following import statement:
    #import <FacebookSDK/FacebookSDK.h>
    1. Now add the following methods to the view controller that contains the Log Out button:

    - (IBAction)logOut:(id)sender {

        

        UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"Are you sure you want to log out?"

                                                           delegate:self

                                                  cancelButtonTitle:@"Cancel"

                                             destructiveButtonTitle:@"Log Out"

                                                  otherButtonTitles:nil];

        

        sheet.actionSheetStyle = UIActionSheetStyleDefault;

        [sheet showInView:self.view];

    }

     

    - (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex

    {

        if (buttonIndex == 0) {

            // Log out

            [FBSession.activeSession closeAndClearTokenInformation];

        }

    }

    In this example, logOut: is the action method for the Log Out button. It displays an action sheet that asks the user if they are sure they want to log out. The actionSheet: method is called when the user taps either the Cancel or Log Out buttons of the action sheet. If they have selected Log Out, the FBSession.activeSession object is passed a closeAndClearTokenInformation message, which logs the user out.

    Figure 23 contains a sequence diagram that shows the object interaction when the user logs out.

    Logging out sequence diagram
    Figure 23 - The Logging Out sequence diagram

     

    Conclusion

    That wraps up the main tasks you need to perform to integrate Facebook login to your iOS apps. If you run into any trouble along the way, I recommend you also check out Facebook's iOS sample app that demonstrates logging in and out, which you can get at this link. If you want to allow users to log in using an email address and password, you can add this functionality to the view controllers that contain your log in and log out methods.

     

    <<Previous

    Master your iPhone in one minute a day: Sign up here to get our FREE Tip of the Day delivered right to your inbox.

    Topics

    Author Details

    Kevin McNeish's picture

    Author Details

    Kevin McNeish

    Kevin McNeish is author of the new book “Learn to Code in Swift” as well as the “iOS App Development for Non-Programmers” book series (www.iOSAppsForNonProgrammers.com), winner of the Publishing Innovation Award. Kevin is also an award-winning app developer, software architect, and conference speaker in the U.S. and abroad. He has spent much of his career making difficult concepts easy to understand. Follow Kevin on Twitter: @kjmcneish.