Master Facebook's OAuth process in iOS


Here we'll show you how to go through the Facebook OAuth process, which lets any Facebook user log in to Facebook and grant your iOS app access to their account. Our app simply logs users in and displays some info about their Facebook profile.

In order to run this example we'll need to provide Facebook with a valid URL which it can redirect us to after we complete both the log in and grant access OAuth steps. For the purposes of this example we'll handle this by running a local web server on the device (or emulator) which we'll use to serve a static HTML file. Both the web server and HTML file are included in the sample application source, which you can download below.

Run our Facebook OAuth Example

1 Log in to Temboo. If you don't already have an account, you can register for free.

2 Download our Facebook OAuth example code and unzip it. Double-click the FacebookOAuth.xcodeproj file in the example code folder to open the project in Xcode. Make sure that you've also downloaded our iOS SDK.

3 Import the Temboo iOS SDK core files and the TMBFacebook.h and TMBFacebook.m files as described in our getting started tutorial.

4 Create a new Facebook app via the Facebook developer console using the Apps menu at the top of the page. Once you've created a new App, click the Settings tab on the left, select + Add Platform, and choose the Website option. Set up your Temboo callback URL by specifying the following URL as your Site URL:

https://ACCOUNT_NAME.temboolive.com/callback/

5 In Xcode, open Supporting Files/FacebookOAuthHelper.m and substitute in your Facebook app details in place of the default values shown below:

    // Provide your Facebook App ID and App Secret.
    static NSString* FACEBOOK_APP_ID = @"YOUR_FACEBOOK_APP_ID";
    static NSString* FACEBOOK_APP_SECRET = @"YOUR_FACEBOOK_APP_SECRET";

6 Additionally, substitute in your Temboo account in place of the default values.

    // Replace with your Temboo credentials.
    static NSString* TEMBOO_ACCOUNT_NAME = @"ACCOUNT_NAME";
    static NSString* TEMBOO_APP_KEY_NAME = @"APP_NAME";
    static NSString* TEMBOO_APP_KEY_VALUE = @"APP_KEY";

7 Run the app in the Xcode emulator. After a few moments you should see a "Facebook Login" button. Click it to log in to Facebook and to grant the sample application access to your Facebook account. Once you've done so, you should be redirected back to your localhost web application where you'll see your Facebook user profile information displayed. That's it!

Taking a closer look at the code

This example includes an OAuth helper class for Facebook and a simple HTML/JavaScript page for finalizing the OAuth flow and displaying user information. The FacebookOAuthHelper class has a few components:

First, the class defines the FacebookOAuthHelperDelegate protocol. Classes which interact with FacebookOAuthHelper must implement these methods in order to be notified when the helper obtains Choreo results:

@protocol FacebookOAuthHelperDelegate <NSObject>
@optional
-(void)authorizationUrlDidLoad:(NSString*)url;
-(void)oauthDidFinalize:(NSString*)accessToken;
@end

When our class is initialized we generate a secure random state token and create a Temboo session object. Creating a state token can be handy in a few ways:

Below is the code for generating the state token:

// Generate a cryptographically-strong random token
self.stateToken = [NSString stringWithFormat:@"facebook-%u", arc4random_uniform(NSIntegerMax)];

To begin the OAuth flow, the ViewController class requests an authorization URL from Facebook by calling the OAuth helper's getAuthorizationUrlWithForwardingURL:delegate: method. That method in turn executes the InitializeOAuth Choreo via the Temboo SDK:

// Executes Facebook.OAuth.InitializeOAuth in order to get an AuthorizationURL
-(void)getAuthorizationUrlWithForwardingURL:(NSString*)url delegate:(id)delegate {
    
    self.loginUrlDelegate = delegate;
    
    TMBFacebook_OAuth_InitializeOAuth *choreo = [[TMBFacebook_OAuth_InitializeOAuth alloc] initWithSession:self.session];
    TMBFacebook_OAuth_InitializeOAuth_Inputs *inputs = [choreo newInputSet];
    
    [inputs setAppID:FACEBOOK_APP_ID];
    [inputs setCustomCallbackID:self.stateToken];
    [inputs setForwardingURL:[NSString stringWithFormat:@"%@?state=%@", url, self.stateToken]];
    
    [choreo executeWithInputs:inputs delegate:self];
}

Note that we use the stateToken as the CustomCallbackID and as a parameter in the ForwardingURL.

When the Choreo returns, the OAuth helper calls the authorizationUrlDidLoad method of the delegate class (ViewController in our case), passing the Facebook authorization URL as an argument. At that point ViewController presents the user with a button which redirects the user to the authorization URL, where the user logs in and authorizes the application to access their account:

-(void)authorizationUrlDidLoad:(NSString*)url {
    NSLog(@"Authorization URL loaded: %@", url);
    self.authorizationUrl = url;
    
    // Hide the spinner
    [self.spinner stopAnimating];
    
    // Update the button text
    NSString *title = @"Facebook Login";
    [self.loginButton setTitle:title forState:UIControlStateNormal];
    [self.loginButton setTitle:title forState:UIControlStateApplication];
    [self.loginButton setTitle:title forState:UIControlStateHighlighted];
    [self.loginButton setTitle:title forState:UIControlStateReserved];
    [self.loginButton setTitle:title forState:UIControlStateSelected];
    [self.loginButton setTitle:title forState:UIControlStateDisabled];
    
    // Make it clickable
    [self.loginButton setEnabled:YES];
}

After the user authorizes the application, Facebook will redirect them back to the redirect URL, which in our case is a simple HTML/JavaScript page hosted locally by the app. Our application watches for new URLs being loaded into the web view, and when it detects the callback URL was loaded initializes the OAuth finalization flow via JavaScript in our local index.html file:

- (void)webViewDidFinishLoad:(UIWebView *)view{
    // Ask JavaScript for the page's URL
    NSString *hostname = [view stringByEvaluatingJavaScriptFromString:@"window.location.hostname"];
    
    if([hostname isEqualToString:@"localhost"]){
        // This is our redirect URL, the user has authorized the app and has been redirected back here
        NSLog(@"Finalizing OAuth");

        // Retrieve and initialize our JS context
        NSLog(@"Initializing JavaScript context");
        self.js = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
        self.js[@"ios"] = self;

         // Finalize the OAuth flow via JavaScript in local index.html
        [self.js evaluateScript:@"finalizeOAuth();"];
    }
}

The last step is to run the FinalizeOAuth Choreo and pass the returned access token to the Facebook > Reading > User Choreo to retrieve your user's profile information. The important thing to note here is that the stateToken is passed to this method from the page and used as the callback identifier in the FinalizeOAuth Choreo. This functionality occurs in the getUserInfo() method:

-(void)finalizeOAuthForDelegate:(id)delegate {
    self. oauthFinalizedDelegate = delegate;
    
    TMBFacebook_OAuth_FinalizeOAuth *choreo = [[TMBFacebook_OAuth_FinalizeOAuth alloc] initWithSession:self.session];
    TMBFacebook_OAuth_FinalizeOAuth_Inputs *inputs = [choreo newInputSet];
    
    [inputs setAppID:FACEBOOK_APP_ID];
    [inputs setAppSecret:FACEBOOK_APP_SECRET];
    [inputs setLongLivedToken:@"1"];
    [inputs setCallbackID:[NSString stringWithFormat:@"%@/%@", TEMBOO_ACCOUNT_NAME, self.stateToken]];
    
    [choreo executeWithInputs:inputs delegate:self];
}

What's Next?

We're all finished! This iOS application executes the OAuth flow, and retrieves information about your app's user. We have OAuth support for many other APIs in our Choreo Library.

Once you've got your code up and running, you're ready to move on and do more. From monitoring your running applications, to moving your generated Temboo code to your preferred development environment and sharing it with colleagues, collaborators and friends - we've got you covered.

Need help?

We're always happy to help. Just email us at support@temboo.com, and we'll answer your questions.


Back