In this article, we discuss how to access and employ data stored in a person’s Facebook
profile to personalize app experiences. Apps that anticipate context and provide
custom experiences based on a person’s preferences will enjoy greater and more
meaningful engagement.
The Personalization Opportunity
Integrating with Facebook enables developers to build highly engaging, deeply social
apps. With Facebook integration, a shopping app can anticipate a person’s preferences
based on the brands and stores they like. A game can select a player’s difficulty level
based on scores and achievements from other games. A music app can predict a
person’s taste based on the artists and venues they love. All of this information is
present in the person’s social graph and can be accessed (provided the person grants
permission) via the Facebook Graph API.
Always keep in mind that people are in control of their own data. We will discuss ways
to fail gracefully in the event a person does not grant (or rescinds) permission for your
app to access data, but be sure to familiarize yourself with Facebook’s approach to
privacy.
The Scrumptious Tutorial
The Scrumptious Tutorial is part of the Facebook SDK for iOS (a corresponding version
for the Facebook SDK for Android is also available). After following the tutorial, you will
be able to build apps that use Facebook for login and authentication, retrieve
information about the person from their Facebook profile, present a person’s Facebook
friends, display a list of nearby Facebook places and post to the Facebook Open Graph.
A completed version of the tutorial is available in the Samples directory of the
Facebook SDK. The techniques mentioned in this article begin with that finished
sample.
Personalizing the Scrumptious User Experience
In the first part of this tutorial, we’ll make a simple adjustment to the Scrumptious
experience based on languages that the person says she speaks. Languages are set in
the "Basic Info" section of your Facebook Profile’s About page. As you can see from my
Facebook profile, I’m proficient in several common languages:

Start by opening the Scrumptious tutorial in Xcode. (You may want to make a copy of it
so that you don’t modify the completed version, but, hey, you also may want to live
dangerously!)
Modify the Scrumptious User Interface
First, let’s modify the Scrumptious interface to include a greeting above our name.
Open SCViewContoller.xib and reposition the label that’s already there a little lower
(it’s blank, so you may need to click around to find it). Then drag and drop a new label to
the Interface Builder and position it above the previous label. In the picture below, I’ve
set the text of the label to "Greeting!" so that you can see what I did.

Option-Click on SCViewController.m in the Project Explorer so that it’s side-by-side with
the XIB file. Control-Click and drag the greeting label to the "@interface" section of the
file and create an Outlet called "greetingLabel":

And, finally, synthesize the property in the "@implementation" section of the file:
@synthesize greetingLabel = _greetingLabel;
Now, our user interface has a label with which we can greet the person using the app.
Let’s change that greeting based on languages that the person says she speaks.
Facebook Permissions
Before accessing a person’s profile information, an app must first request permission
and the person must grant it. When a person logs into an app using Facebook and the
app requests no additional permissions, the app will receive access to basic
permissions, including the profile ID, person’s name (first and last), username, gender,
and location.
Apps may request extended permissions, which will permit the app to retrieve more
information from a person’s Facebook profile or write certain kinds of data on behalf of
the person. Each of these permissions must be requested explicitly and a person can
elect to opt out of each of these individually. You’ve probably seen a dialog box like this
before:

Open Graph permissions enable an app to publish certain types of actions to the
Facebook Open Graph. (Note: Open Graph integration is covered in detail in the
Scrumptious tutorial, section 5)
Finally, User and Friend permissions enable an app to obtain detailed information from
someone’s Facebook profile. These permissions are slightly different than the others.
Where Facebook extended permissions allow the person to opt-out, User and Friend
permissions do not. Therefore, it’s very important for apps to only request them when
necessary. There is a correlation between apps that request additional Facebook
permissions, and the number of people who abandon the app before completing the
login process.
Lastly, remember that only read permissions may be obtained when the Facebook
session is created. Write permissions, which we will not discuss in this tutorial, should
be obtained when the person is about to perform an action in which they are required.
Request permission to get a person’s information
Information about the languages that a person speaks may be obtained by requesting
(and receiving) the user_likes permission. Let’s first modify the original permissions
request call in the openSessionWithAllowLoginUI method in the SCAppDelegate.m file
to ask for the user_likes permission:
- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI {
return [FBSession openActiveSessionWithReadPermissions:[NSArray
arrayWithObject:@"user_likes"]
allowLoginUI:allowLoginUI
completionHandler:^(FBSession
*session, FBSessionState state, NSError *error) {
[self
sessionStateChanged:session state:state error:error];
}];
}
Retrieving information from Facebook
Let’s take a look at the result of asking for the person’s languages. To do so, we can use
a tool called the Facebook Graph Explorer. The Graph Explorer, shown below, lets us run
queries on the Facebook graph and retrieve information:

After obtaining an Access Token, we can run a query to obtain the list of languages for a
person (in this case, me):
{
"id": "566480611",
"name": "Prashant Sridharan",
"languages": [
{
"id": "113301478683221",
"name": "American English"
},
{
"id": "112929422054734",
"name": "Profanity in American Sign Language"
},
{
"id": "108462045844299",
"name": "Franglais"
},
{
"id": "113599388650247",
"name": "Klingon"
}
]
}
What we obtain is a dictionary, which we can then query. For example, to iterate over
this list and print the name of each language, we simply write the following Objective-C
code:
NSArray *languages = [user objectForKey:@"languages"];
for (int i = 0; i < [languages count]; i++) {
NSLog(@"Language: %@", [[languages objectAtIndex:i]
objectForKey:@"name"]);
}
Use Permissions to Personalize the App Experience
Now that we know how to query the Facebook Graph for data, let’s modify our app to
show a different greeting based on the languages we see. Specifically, let’s provide a
Klingon greeting if the person admits to speaking Klingon.
To do so, we’ll add the following to the end of the populateUserDetails method in the
SCViewController.m file:
[FBRequestConnection
startForMeWithCompletionHandler:^(FBRequestConnection *connection,
id<FBGraphUser> user,
NSError *error) {
if ([user objectForKey:@"languages"]) {
NSArray *languages = [user objectForKey:@"languages"];
for (int i = 0; i < [languages count]; i++) {
NSLog(@"Language: %@", [[languages objectAtIndex:i]
objectForKey:@"name"]);
if([[[languages objectAtIndex:i] objectForKey:@"name"]
isEqualToString:@"Klingon"]) {
self.greetingLabel.text = @"Heghlu'meH QaQ jajvam!";
}
}
}
}];
This code first determines that we have a languages element in the dictionary (after all,
some people may not have specified any languages at all, in which case the result will
be nil). From there, it iterates over the ID/name pairs, looking for a pair whose name is
"Klingon". If it finds that pair, it changes the text of the greeting to "Heghlu'meH QaQ
jajvam!" (this is the Klingon phrase for "It is a good day to die." According to Marc
Okrand’s definitive "The Klingon Dictionary," Klingons don’t bother with societal
niceties like "hello" and "greetings," so this is the best we can do)
Our finished application looks like this:
Fail Gracefully
But, what if a person hasn't granted permission for user_likes? In that case, our app
needs to handle this situation gracefully. What we will do is first set the default value
of the greeting label, then query the active permissions for the current person using the
app and see if they have provided it:
self.greetingLabel.text = @"Hello";
if (!([FBSession.activeSession.permissions
indexOfObject:@"user_likes"] == NSNotFound)) {
}
If they have, we will execute the code in the previous section. If not, then the default
value of the greeting label is already set.
Personalization: the New Frontier
This is an extraordinarily rudimentary example of querying the Facebook Graph for
data and then tailoring an app experience based on that information. How far you
decide to take this personalization effort is up to you. Complex algorithms for
personalization and recommendations aside, there is a lot you can do by querying
information and building custom app behavior. However, remember to keep a few
things in mind:
- Don’t ask for too many permissions, or the person may opt out. Always give the
person concrete reasons why you are requesting such permissions. Earn their trust.
- Don’t ask for permissions all at once. Progressively ask for more permissions as
people encounter features in your app that require them.
- Have a definitive and easy to comprehend policy in place that explains to people
how and why you will use their data.
Providing contextual and personalized experiences is the next stage of the social web.
It parlays people’s data into far more immersive apps, but, in turn, it requires app
developers to be creative, smart, and responsible. The payoff can be significant, but as a
wise man once said, "With great power comes great responsibility."
Prashant Sridharan is a Developer Advocate at Facebook, where he helps developers around the world learn how to build great apps using the Facebook platform. Prior to Facebook, Prashant was the Director of Marketing for Amazon Web Services, the chief Product Manager for Microsoft Visual Studio, a product manager at various startups, and a software developer at Sun Microsystems. He is well past the "yucky" phase with Objective C and LOVES to build iOS apps, adores Ruby on Rails, and spends every moment of his free time either snowboarding or training for snowboarding season.