Friday, May 14, 2010

Facebook Connect

UPDATE: This post was written for the Facebook REST API. The REST API is now deprecated and you should use the Graph API instead. I may write a new post on the Graph API in the future.

This time I’m returning to a topic I learned months ago - Facebook Connect. However, I need a refresher on it. One of the great luxuries of programming is adding functionality without writing the code personally. Fortunately, Facebook has created an API that works well on a multitude of platforms. With this API, an iPhone app can become more interactive as users share with others what they are doing with it. This also results in an app receiving greater visibility to the public.

Anyway, several months ago I added Facebook and Twitter support to Police Scanner 2. My biggest struggle with implementing Facebook support was that the iPhone documentation is very minimal and not as explicit as I would like. I figured out almost everything simply by trial and error. Hopefully this blog post will shed more light on the subject.

This tutorial is lengthy, so I will start with an overview of the steps:
  1. Create a Facebook app.
  2. Download and copy Facebook Connect into your source code.
  3. Create an FBSession with your API key and secret key.
  4. Login to Facebook via a FBLoginButton or FBLoginDialog.
  5. Enable auto re-login.
  6. Create delegate(s) that conform to the FBSessionDelegate and FBRequestDelegate protocols.
  7. Request the permissions you need.
  8. Perform actions with FBRequest.
One of the first steps to take in implementing Facebook Connect is creating a Facebook app on Facebook itself. To do this, you must add the Facebook Developer app to your profile. Finding the app is near impossible. I found it through a link on the developers page. The URL to the app is http://www.facebook.com/developers/. From there a Facebook version of your app can be created. Even though you are creating an “app,” you won’t be using it as an app. Instead, this will be the channel through which your iPhone app will interact with Facebook. This also provides some basic analytic information and creates a Facebook page for your app. I won’t go into any of the details of how to set everything up. That could be a lengthy topic by itself. Personally, I found the basics to be straightforward enough. There are many advanced capabilities that can be explored if you so desire.

With your Facebook app in place, you can now start adding the functionality to your iPhone app. You will need the Facebook Connect Xcode project. You can Google it or find it here. I found it easiest to copy the Facebook Connect project code into your own project. The greatest part of Facebook Connect is that almost everything is done for you.

Once the code is copied into your project, just #import “FBConnect.h”. Next, create a FBSession object. You should retain this object for the lifetime of your application. This is where you will need your previously created Facebook app. On the application settings editor page there is an API key and app secret key. These are necessary for creating your session object. They can be stored as string constants and passed in as parameters. the following gives an example of this.
session = [[FBSession sessionForApplication:FBAPIKey secret:FBSecretKey delegate:self] retain];

Next, to login to Facebook. This can be two different ways. The easiest is to create a FBDialogButton and add it wherever you please. If my memory serves me well, there are three different sizes of buttons that can be used. Alternately, you can create a FBLoginDialog and call that however you like. This can be done as follows:
FBLoginDialog * dialog = [[[FBLoginDialog] alloc] initWithSession:session] autorelease];
[dialog show];
Either way, a nice login dialog pops up and takes care of everything.

Facebook Connect handles automatic re-login. All you need to do is call [session resume]; when your app starts. If a user has never logged in or explicitly logged out, then this will do nothing. Also, sessions automatically expire if they are left idle for two hours.

I failed to mention earlier that you will need an object that conforms to the FBSessionDelegate protocol in order to create a session. It has a single required method:
- (void)session:(FBSession *)session didLogin:(FBUID)uid;
You can use this method as an opportunity to set a flag in your app that the user has logged into Facebook. This is also a great opportunity to request any permissions you will need later.

While on the topic of permissions, I will expound some more. FBPermissionDialog is used to request different permissions. This has two delegate methods as defined in FBRequestDelegate.
- (void)dialogDidSucceed:(FBDialog *)dialog;
- (void)dialogDidCancel:(FBDialog *)dialog;
It should be clear which does what and when it is called. The following is an example of requesting permission to publish to a user’s stream:
if (!FBPermissionsGranted) {
        FBPermissionDialog * dialog = [[[FBPermissionDialog alloc] init] autorelease];
        dialog.delegate = self;
        dialog.permission = @"publish_stream";
        [dialog show];
}

There are several different permissions that can be requested. Consult the Facebook documentation for the specifics. The only change that needs to be made to the following code is the string representing the desired permission.

One important note, Facebook remembers if a permission was previously granted. So if you request the permission a second time, the dialog window pops up and immediately closes. This quick flash is annoying and should be avoided. This can be done by saving the state of permissions granted and/or making an API call that requests the user’s granted permissions.

Now that you’ve got a user to login and granted the necessary permissions, let’s have your app do something. This is done through FBRequest. A request will look something like this:
[[FBRequest requestWithDelegate:self] call:@“some action here...” params:params];
The string is the API call to use. For example, to publish to a user’s stream call @“facebook.stream.publish” or update a user’s status with @“facebook.Users.setStatus”. The params is an NSDictionary that contains the parameters specific to that API call. Consult the Facebook API for the details. Some parameters are optional whereas others are required. If we were to publish something to the user’s stream we could set up the parameter like this:
NSDictionary *params = [NSDictionary dictionaryWithObject:@“Hello World!” forKey:@"message"];

FBRequests are where the action of Facebook Connect comes in. With the proper permissions you can do anything with a FBRequest. For example, you can upload videos, check if a user is a fan of a particular page, create events, etc. Basically, anything you can do on the Facebook website, you can do from the API. Just call the desired method, such as “video.upload,” “page.isFan,” or “events.create,” then pass in the necessary parameters. Facebook even has their own query language (FQL). This is comparable to SQL. Another point to note is that Facebook also provides a test console with each API call to test if a call works and what exactly it is returning.

I hope this lengthy tutorial is beneficial. I provided only simple examples, but really your imagination is the limit. Most of the process is very implement. The challenge comes in when making requests. Getting the parameters and return values right can take some trial and error. Making use of the Facebook test console makes life much easier.