In this recipe, we will learn how to implement the Single Sign On feature of the Facebook iOS SDK that will enable our application to communicate with Facebook.
The process of using SSO works by redirecting the user to the Facebook iOS application on their device, and presenting them with an authentication dialog box, showing only those permissions that your application has been configured to use.
Following on from our previous recipe, ensure that our SocialNetworkApp
project file is open.
To begin, follow the simple steps as outlined in the given order:
AppDelegate.hinterface
file from the Project Navigator.// AppDelegate.h // SocialNetworkApp // Created by Steven F. Daniel on 11/12/12. // Copyright (c) 2012 GenieSoft Studios. All rights reserved. #import <UIKit/UIKit.h> #import "FBConnect.h" @class ViewController; @interface AppDelegate : NSObject <UIApplicationDelegate, FBSessionDelegate, FBDialogDelegate> { Facebook *facebook; } // Create the required class Setters and Getters @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) ViewController *viewController; @property (nonatomic, retain) Facebook *facebook; -(void)fbDidLogin; -(void)fbDidLogout; -(void)fbSessionInvalidated; @end
AppDelegate.m
implementation file from the Project Navigator.// AppDelegate.m
// SocialNetworkApp
// Created by Steven F. Daniel on 11/12/12.
// Copyright (c) 2012 GenieSoft Studios. All rights reserved.
#import "AppDelegate.h"
#import "ViewController.h"
@implementation AppDelegate
@synthesize window = _window;
@synthesize viewController = _viewController;
@synthesize facebook;
didFinishLaunchingWithOptions:
method as shown in the following code snippet:- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]] autorelease]; // Override point for customization after application // launch. self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController" bundle:nil] autorelease]; self.window.rootViewController = self.viewController; // Do any additional setup after loading the view, // typically from a nib. self.facebook = [[Facebook alloc] initWithAppId:@"YOUR_APPID_HERE" andDelegate:self]; // Check and retrieve authorization information NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; if ([defaults objectForKey:@"FBAccessTokenKey"] && [defaults objectForKey:@"FBExpirationDateKey"]) { self.facebook.accessToken = [defaults objectForKey:@"FBAccessTokenKey"]; self.facebook.expirationDate = [defaults objectForKey:@"FBExpirationDateKey"]; } // Check to ensure that we have a valid session object if (![self.facebook isSessionValid]) { [self.facebook authorize:nil]; } [self.window makeKeyAndVisible]; return YES; }
-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { return [self.facebook handleOpenURL:url]; } -(BOOL)application:(UIApplication *)application openURL:(NSURL *)urlsourceApplication:(NSString *)sourceApplication annotation:(id)annotation{ return [self.facebook handleOpenURL:url]; } -(void)fbDidLogin { // Check and retrieve authorization information NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:[self.facebook accessToken] forKey:@"FBAccessTokenKey"]; [defaults setObject:[self.facebook expirationDate] forKey:@"FBExpirationDateKey"]; [defaults synchronize]; } - (void)fbDidLogout { // Remove saved authorization information if it exists NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; if ([defaults objectForKey:@"FBAccessTokenKey"]) { [defaults removeObjectForKey:@"FBAccessTokenKey"]; [defaults removeObjectForKey:@"FBExpirationDateKey"]; [defaults synchronize]; } UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"FaceBookSampleApp" message:@"Your session has logged out." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; [alertView show]; [alertView release]; } [alertView show]; [alertView release]; } #pragma mark Called when the session has expired. - (void)fbSessionInvalidated { UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"FaceBookSampleApp" message:@"Your session has expired." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; [alertView show]; [alertView release]; [self fbDidLogout]; }
In this recipe, we started by extending our class to include the FBSessionDelegate
and FBDIalogDelegate
class
protocols, as well as its methods. We then declared an instance variable called facebook
that will enable us to access the Facebook
class methods. Next, we added a property instance of the Facebook
class to create the class getters and setters and then proceeded to synthesize our facebook
variable that we defined within the
AppDelegate.h
interface file. This is done so that we can make our implementation file aware of the facebook
variable, so that we can access the object properties and methods. In our
didFinishLaunchingWithOptions:
method, we initialize our Facebook
object to invoke the SSO, by passing in the application AppID that we created when we registered our iOS mobile app, as well as the Graph API and Platform Dialogs from within our app. Once the object has been instantiated, we need to check for any previously saved access token information and then use this saved information to set up a valid session, by assigning the saved information to the Facebook access token and expiration date properties to ensure that your app does not redirect to the Facebook application. Invoke the authorization dialog box, if the application already has a valid access_token
.
We proceed to check for a valid session and if it is not valid, we call the authorize
method which will log the user in and prompt the user to authorize the application and then declare two methods that will be called by the iOS when the Facebook application redirects to the app during the SSO process. These methods provide the app with the user's credentials.
You will notice that we have declared two different methods that will be used to handle different versions of the iOS app. The handleOpenURL:
method is for versions prior to Version 4.2, and the openURL
one is for Versions 4.2 and greater. In our next step, we implement the Facebook fbDidLogin:
method of FBSessionDelegate
. After the SSO process has successfully signed in and the Facebook app redirects back to the calling application, we save the user's credentials using the FBAccessTokenKey
and FBExpirationDateKey
keys, and then save these into the user preferences NSUserDefaults
.
We then proceed to implement the Facebook fbDidLogout:
method of FBSessionDelegate
. After the SSO process successfully signs out of the iOS app, the callback
method gets called. We need to check to see if we have a successful access token key prior to removing the stored user's credentials, using the FBAccessTokenKey
and FBExpirationDateKey
keys.
We then remove those details from the user preferences using the NSUserDefaults
object. Finally, we create an instance of the UIAlertView
dialog box to notify the user that a successful logout has happened. In our previous sections, we implemented the Facebook fbSessionInvalidated
method of FBSessionDelegate
. When a request is made to post a new message to the current user's wall or to send notifications to your friends, the fbSessionInvalidated
method is called to ensure that a valid session exists. This uses the session
object, created by the SSO process when your application signed in. If the session state has expired, we declare an instance of the UIAlertView
class to display a message to the user, before finally making a call to the fbDidLogout
method to ensure that all of the required access tokens are removed cleanly.
If a user is already signed into the Facebook iOS application on their device, he won't need to provide this again. The process of using SSO works by redirecting the users to the Facebook iOS application on their device, and presenting them with an authentication dialog box, showing only those permissions that your application has been configured to use. Once the user has allowed those permissions requested by your iOS app, they will be redirected back to your application with the appropriate access token.
When using the Facebook SSO process, certain things can behave slightly differently depending on what version of the Facebook iOS app has been installed on the user's iOS device.
The following table explains what happens when the Facebook SSO process is run under certain conditions:
Facebook SSO condition |
Description |
---|---|
iOS application is running with a version of iOS that supports multitasking and running Version 3.2.3, or greater of the Facebook iOS app. |
The Facebook SDK will attempt to open the authorization dialog box within the Facebook app. After the user grants or declines authorization, the user is redirected back to the calling application, passing back with it an authorization token, expiration, and any other parameters the Facebook |
iOS device running with a version of iOS that supports multitasking, and isn't running Version 3.2.3, or greater of the Facebook iOS app. |
The Facebook SDK will open the authorization dialog box within Safari. After the user grants, or declines authorization, Safari will redirect the user back to the calling application. This process is similar to the Facebook app authorization, and allows for multiple apps to share the same Facebook user |
If the iOS application is running a version of iOS that does not support multitasking. |
The SDK will use the old mechanism of popping up an inline |