Marketing In Code, Part 2: Setting A User's Status In Facebook From An iPhone App — A Tutorial

By
On June 10, 2009

In part one of this series we ran the numbers and found that posting a status update to 13 average Facebook users generated as much exposure as spending the entire post-commission revenue for an average priced app in the top-100.

In this tutorial, you’ll learn how post status updates from an iPhone:

Outline

There are, broadly speaking, two big moving pieces to this tutorial:

  1. Setting up a Facebook application
  2. Adding Facebook capabilities to an iPhone application

Facebook Application

First thing we need to do is create a Facebook Application inside Facebook.

Creating an application will:

  1. Give us an API Key and Application Secret, the two elements we need to authenticate for Facebook API access from the iPhone
  2. Provide a via/source label for the status updates — e.g., “Dan Grigsby is writing a Facebook iPhone tutorial • 10:12am • via Some iPhone App”

No Server Back-End

Updating a user’s status from an iPhone doesn’t require a server back-end. All of the Facebook API calls will be generated from the phone using Facebook Connect for iPhone, which we’ll set up shortly.

Creating A Facebook Application

To create an application in Facebook you first have to add Facebook’s Developer Application to your Facebook account.

If you have not already added the Developer Application do so now:

  1. Login to Facebook
  2. Visit the Developer Application page
  3. Click the Allow button

Next, add a new application from the Developer Application page:

  1. Click the button at the top of the page
  2. Enter an Application Name; read the Facebook terms and, if you agree, select the Agree radio button; click Save Changes . The Application Name you provide will be used as the via/source label in the status updates

Your app has now been created. Note the API Key and Secret listed in the Essential Information section of the page. In a later step, you’ll use these to authenticate your application from the iPhone.

Note: this is the minimum Facebook Application setup to support sending updates from your iPhone code. On your own, you’ll want to fancy it up with icons, have your application verified by Facebook, and place it in the Application Directory.

iPhone Code

We’ll create a simple, single view sample app to demonstrate setting status from Facebook from the iPhone.

Source

The sample app uses of Facebook’s own Facebook Connect for iPhone and some helper classes I’ve created.

To download Facebook Connect for iPhone:

  1. Visit the Facebook Connect for iPhone page
  2. Click the Download the SDK link
  3. Unzip the downloaded archive

My helper classes are stored at GitHub. To download my helper classes clone their git repository:

  1. Open a terminal window and type: git clone git://github.com/dcgrigsby/MOFBHelper.git

Note: You’ll include Facebook connect and my helper classes app by dragging-and-dropping virtual folders from their respective Xcode projects into yours. Consequently, you’ll want to place your local copies somewhere predictable, semi-permanent, and with an easily referenced path. E.g., placing them on the desktop is probably not a good place for them. I keep all of my work in ~/Projects; I keep the Facebook Connect and helper classes in ~/Projects/fb-connect and ~/Projects/MOFBHelper respectively.

Sample App

We’ll create a simple, single view app that handles Facebook login and status update in four steps:

  1. Create the app
  2. Add Facebook Connect for iPhone to the project
  3. Add my helper classes to the project
  4. Add Facebook login and status update code

Create The App

Launch Xcode and create a new View-based iPhone application called StatusUpdater:

  1. Create a new project using File > New Project… from Xcode’s menu
  2. Select View-Based Application from the iPhone OS > Application section, click Choose…
  3. Name the project as StatusUpdater and click Save

Add Facebook Connect For iPhone To The Project

When I sat down to learn Facebook Connect for iPhone this was the step that caused me the most grief. Essentially, we’re going to copy part of another Xcode project into our own project, then we’re going to configure the project to include find the headers it needs to build properly. I’ll walk you through it a step at a time:

  1. In Finder, navigate to the folder that contains the Facebook Connect for iPhone source. The folder is usually named fbconnect-iphone
  2. While still in Finder, open up the src subdirectory
  3. Locate FBConnect.xcodeproj and double-click to open it in Xcode. You should now have two open Xcode projects: StatusUpdater and FBConnect
  4. In the Groups & Files panel of the FBConnect Xcode project, expand the blue FBConnect project branch
  5. Select the yellow FBConnect folder with your mouse and drag-and-drop it onto the StatusUpdater project icon in the StatusUpdate Xcode project. Important: drag and drop the FBConnect folder, not the FBConnect project itself!
  6. Add the items to the StatusUpdater Xcode project by clicking the Add button. Do not copy items into the destinations group’s folder, but do make sure that they will be added to the StatusUpdater target
  7. In the Groups & Files panel of the StatusUpdater Xcode project, select the StatusUpdater project icon and bring up the project’s Info window by clicking the big blue-i/info button at the top of the window
  8. Select the Build tab
  9. Locate and double click the Header Search Paths item in the Search Paths section
  10. Click the + button to add a search path
  11. Enter the path to the Facebook Connect for iPhone src directory — e.g., ../fbconnect-iphone/src
  12. Click OK to add the search path and close the info window

Check your work by building the project. You can safely ignore the setFont warning. If the build fails, confirm that you did the drag-and-drop operation correctly — your Groups and Files panel should look like the image at right — and verify the Header Search Path.

Add My Helper Classes To The Project

Adding my helper classes to the project follows a similar, but slightly simpler approach to the above:

  1. In Finder, navigate to the folder that contains the git clone of the helper classes. The folder is usually named MOFBHelper
  2. Locate MOFBHelper.xcodeproj and double-click to open it in Xcode. You should now have two open Xcode projects: StatusUpdater and MOFBHelper
  3. In the Groups & Files panel of the MOFBHelper Xcode project, expand the blue MOFBHelper project branch
  4. Select the yellow MOFBHelper folder with your mouse and drag-and-drop it onto the StatusUpdater project icon in the StatusUpdate Xcode project. Important: drag and drop the MOFBHelper folder, not the MOFBHelper project itself!
  5. Add the items to the StatusUpdater Xcode project by clicking the Add button. Do not copy items into the destinations group’s folder, but do make sure that they will be added to the StatusUpdater target

Your your Groups and Files panel should look like the image at right.

Add Facebook Login And Status Update Code

My helper classes make posting a status update as simple as setting a property on an instance of the helper class — e.g., fbHelper.status = @"reading Mobile Orchard";

Before we can do that, however, need to have the user log in to Facebook and give our app permission to update their status. For the former, the sample app contains code to show a login button and post an update after the user has logged in. The latter is handled automatically by my helper classes — if you set the status property and the user hasn’t given your app permission, a dialog will pop up asking them to do so.

There’s very little code, so I’ll paste it in next and walk you through it below:

Use this code for StatusUpdaterViewController.h:

#import <UIKit/UIKit.h>
#import "FBConnect/FBConnect.h"
#import "MOFBHelper.h"

@interface StatusUpdaterViewController : UIViewController <FBSessionDelegate, MOFBHelperDelegate> {
	FBSession *session;
	MOFBHelper *fbHelper;
}

@end

Use this code for StatusUpdaterViewController.m:

#import "StatusUpdaterViewController.h"

@implementation StatusUpdaterViewController

#pragma mark View Methods

- (void)viewDidLoad {
	[super viewDidLoad];

	session = [FBSession sessionForApplication:@"YOUR APP'S API KEY!!!" secret:@"YOUR APP'S SECRET" delegate:self];

	FBLoginButton* button = [[[FBLoginButton alloc] init] autorelease];
	[self.view addSubview:button];

	fbHelper = [[MOFBHelper alloc] init];
	fbHelper.delegate = self;
}

- (void)viewDidAppear:(BOOL)animated {
	[super viewDidAppear:animated];
	[session resume];
}

#pragma mark Facebook Session Protocol Methods

- (void)session:(FBSession*)session didLogin:(FBUID)uid {
	fbHelper.status = @"is learning to set Facebook status programatically from an iPhone";
}

#pragma mark Optional MOFBHelper Protocol Methods

- (void)statusDidUpdate:(MOFBHelper*)helper {
	NSLog(@"status updated");
}

-(void)status:(MOFBHelper*)helper DidFailWithError:(NSError*)error {
	NSLog(@"status update failed: %@", [error description]);
}

# pragma mark Housekeeping

- (void)dealloc {
	[session release];
	[fbHelper release];
	[super dealloc];
}

@end

Note: Be sure to change the API Key and Secret in the call to sessionForApplication:secret:delegate:self

In viewDidLoad, the code adds a Facebook login button to the view, and creates/configures an instance of my helper class.

In viewDidAppear:, we resume the session. If the user previously checked the “keep me logged in” box during a Facebook login the session will automatically resume; otherwise a login dialog will be displayed. In either case, after the session is created the session:didLogin: method is called. We send the resume method here, and not in viewDidLoad because the view needs to be on-screen in order to show the login dialog.

The session:DidLogin method updates the status. If the user has not already granted permission for our app to update the status then a dialog asking permission will be displayed.

The MOFBHelper class defines an optional protocol to inform the app whether or not the status update was successful. The statusDidUpdate: and status:DidFailWithError: methods are called as appropriate. The error codes are define in the MOFBErrors.h file. If you don’t care about the success or failure of a status update you can remove these methods and the MOFBHelperDelegate from the protocols section of the .h file.

Next

MOFBHelper aims to be a higher-level interface to Facebook Connect for iPhone. If there’s enough interest — measured by comments to this points, re-tweets, back-links and github project watchers — I’ll expand it to support other Facebook actions. Contributors welcome. Finally, be constructive with your feedback.

Thanks to our sponsor: The iPhone UI icon set gives app developers an extensive library of icons for use in their Tab Bar and Tool Bar item objects. 120 png icons and a sample app for browsing the set – $69.

0 responses to “Marketing In Code, Part 2: Setting A User's Status In Facebook From An iPhone App — A Tutorial”

  1. Billy Gray says:

    “Arrr, this be pleasin’ to me eye!” I still haven’t gotten over the Pirate language setting.

    Anyway, excellent tutorial, easy to follow, very straight-forward.

    Something that I didn’t quite get working is having my app’s name shown on Facebook. You can see what showed up for me in my feed over here. Switching the language back to normal English didn’t fix it. This may be a case of “Billy should have copied and pasted the code instead of typing it in himself,” but I’m having trouble figuring out what I missed.

    This is a rad cool lib, I plan on using it in an app. Will definitely contribute back any changes via Github 😉

  2. Billy Gray says:

    Oi, turns out you don’t see the name of the app on your own feed, but if you look at your own profile view, you see it there. I guess facebook makes the assumption that you don’t need to know where you sent the update from!

  3. Manpreet Singh says:

    Saw some warnings while compiling MOFBHelper. Got rid of them by basically separating the two delegates – MOFBHelperDelegate and MOFBStatusDelegate.

    Here’s what the headers look like now:

    —————–
    #import
    #import “MOFBStatus.h”

    @class MOFBHelper;

    @protocol MOFBHelperDelegate
    – (void)statusDidUpdate:(MOFBHelper*)helper;
    -(void)status:(MOFBHelper*)helper DidFailWithError:(NSError*)error;
    @end

    @interface MOFBHelper : NSObject {
    id delegate;
    MOFBStatus *mofbStatus;
    }

    @property (nonatomic, assign) id delegate;
    @property (nonatomic, retain) NSString *status;

    @end
    ————–

    ————
    #import
    #import “FBConnect/FBConnect.h”
    #import “MOFBPermission.h”

    @class MOFBStatus;

    @protocol MOFBStatusDelegate
    -(void)statusDidUpdate:(MOFBStatus *) status;
    -(void)status:(MOFBStatus *) status DidFailWithError:(NSError*)error;
    @end

    @interface MOFBStatus : NSObject {
    id delegate;
    NSString *status;
    }

    @property (nonatomic,assign) id delegate;
    @property (nonatomic,retain) NSString *status;

    – (void)update:(NSString *)string;

    @end
    ——————–

  4. KaffeineComa says:

    Hi, thanks for this great tutorial. Is there any way to add the Facebook icon to a toolbar? IB won’t seem to let me drag it there. I also tried adding a standard (RoundRect?) button to the IB toolbar and then simply changing the icon, but the icons provided by Facebook don’t render properly against the Toolbar background.

    Thanks.

  5. KaffeineComa says:

    BTW I had an app rejected recently for hanging when there is no network available. If you decide to use Facebook Connect, I highly recommend implementing some sort of network detection, as the FB Connect seems to just hang when there are network issues (e.g. Airplane mode).

  6. Chang says:

    Is there a way to not show the facebook button? It works fine when I show the button as in the tutorial. But when I tried to hide the button, it gives me exception of “Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘*** -[NSCFDictionary setObject:forKey:]:attempt to insert nil value (key: api_key)’

  7. Chang says:

    Ok, my workaround is to show the button in another setup view and it works fine. It seems you are required to show the button somewhere in your app. But now I got the network issue in KaffeineComa’s post. This facebook connect for iphone could have been better documented for this kind of issues.

  8. Unowen says:

    Chang,

    Thanks. Adding the button to the view (even if not visible) did fix the api_key crash.

  9. Ken says:

    When try to add a FBLogin button to UITableViewCell, this button does not appear. But when you try to select this cell, You can see this button. After this the button seem to appear.

  10. Unowen says:

    so, adding the login button fixes the api_key crash, but now I’m getting a
    Program received signal: “EXC_BAD_ACCESS”
    error when using fbHelper.status to update the status

  11. Andrew says:

    Is there a way to add a link or picture to the status update.

    This has been the easiest add to my program, i spent 3 hours fiddling with the Facebook Connect and still has no luck with any of it.

  12. Nik says:

    thankyou! can’t wait to get my handy dirty with these helper classes!

    took me an hour to figure out how to just not use the FBLoginButton! and the next two hours to get my head around the api key value pairs!

  13. DenVog says:

    Really nice. Thanks for sharing Dan. I have to say, this is much more helpful than the Facebook in 5 Minutes video.

    For those that want to be specific in where they put the facebook button, here are a couple lines that might save you some searching. Replace the following in viewDidLoad:
    [self.view addSubview:button];
    with:
    //define size and position of button: x-position, y-position, width, height
    button.frame = CGRectMake(8, 406, 100, 45);
    // secondaryView is the name of my flipside UIView
    [secondaryView addSubview:button];

    Thanks again. Do you have a standard credit blurb for people that want to use your classes in their application?

  14. DenVog says:

    I’d request that Part 3 include information on how to implement specific functions. For example, how do I present the user with a “Become a Fan” button within your iPhone app. I’ve been going through the Facebook API docs, but don’t see any guidance for doing this, other than using their Fan Box. WordFu seems to have figured it out though.

  15. Mustafa says:

    Thanks for a great tutorial. I’m interested in knowing if i can get rid of Facebook’s default “Connect to Facebook” screen. I want to use my own custom interface for storing the username/password, so that every time user starts my application, i automatically log him in and start updating status when ever i want without popping any interfaces?

  16. Mustafa says:

    Another question? Can i avoid specifying Header Search Paths item in the Search Paths section? Why can’t i just include the files in my project and use them?

  17. DenVog says:

    Is than an update to the code for use with iPhone OS v3.x? I get an error that I don’t see for 2.x builds:
    error: property ‘session’ attempting to use ivar ‘_session’ declared in super class of ‘FBLoginDialog’

  18. If you have the luxury of working with a server, you should consider not embedding your Facebook app’s secret key in your iPhone app, as this poses a potential security risk. Unfortunately, the documentation on the Facebook wiki leaves a lot to the imagination on how to accomplish this. Here is some info on how to implement a Facebook Connect for iPhone session proxy in PHP.

  19. Scott says:

    If you ‘hide’ the button, how do you *call* the necessary method to activate the whole process? I am dense (and also very frustrated).

    I assume that touchUpInside needs to be called, but I cannot accomplish.

    Any assistance is appreciated.

    Thanks.

  20. HuanNguyen says:

    Hello
    I’m writting a game for iphone by cocos2d.I want to use fbconnect to show result on facebook.But i don’t know how to add it on my project.
    please help me.

  21. Luis says:

    Hey all, what is the best what to share a URL on the iPhone, and is there a way to allow a user to preview first?

  22. Luis says:

    Is there a way to verify the session before posting a status update with MOFBHelper?

  23. Wally says:

    Sorry for the newbie question, but how can I implement this to provide the posting of a feed/update from several different places in my app? I have several different viewcontrollers with UIActionSheet’s and wanted to include a “Post to Facebook” in each of these viewcontrollers. I have a single FB login button placed in a Settings viewcontroller to enable the login. However, if a user logs-out of FB, I’d still like to provide the user with the ability to login + post if they select the UIActionSheet selection for “Post to Facebook”, whereby it would detect if the user is indeed logged-in, and if not would fire-up the FB login dialog and upon successfully logging-on, would then fire-up the FBStreamDialog to enable the user to enter info to post. It works just fine if I keep it all in one viewcontroller, but wondering what I need to do in order to share the session information across multiple viewcontrollers. Do I place the login button and session stuff in the app delegate instead?

  24. Vico says:

    Great Job, I was stucking for a couple of days, and I just found your tut now, it’s so easy, thank you 🙂

  25. Arcank says:

    Thanks for this great tutorial!
    I tried to use your helper class, without using the button. It crashes indeed, because of the `api_key` that it tires to set to nil.
    Using the button (hiding it), I have a new problem. When the view of your controller is dismissed, the dealloc mthod of the FBLoginButton is called, and inside it, [_session.delegates removeObject:self].
    It causes a EXC_BAD_ACCESS, because `_session` cas previously deallocated (and not reset to `nil`…).
    Any idea?

  26. Ryan Christianson says:

    I found that to get the button to show up I needed to call this after I added it to a view:

    [loginButton setHighlighted:NO];

  27. Hi Dan-

    I really appreciate this intro to facebook connect for iPhone and the corresponding tools. I referenced your post in a tutorial I wrote today: https://blog.getlimed.com/lime/2010/03/add-facebook-connect-to-a-unity-iphone-game.html

    In case you don’t recall, we had an interesting conversation at lunch at last year’s iDev 360 in Denver.
    Thanks again.

  28. Thanks ever so much for your help, the example code work really well.