Integrating OpenFeint with Cocos2D-iPhone Applications
OpenFeint is a service that enables your iPhone/iPod Touch application the ability to provide online score tracking. The service is free and can easily be incorporated into your applications. This tutorial will cover the integration of OpenFeint 2.4.3 with the Cocos2D-iPhone framework. Before getting started, it is assumed that you already have familiarity with:
- Objective-C
- XCode
- Cocos2D-iPhone framework
The expectation is that you already have a working Cocos2D based application to which you’d like to enable leaderboard functionality. If you’re new to Cocos2D-iPhone, then you should visit http://www.cocos2d-iphone.org to review the available documentation and download the latest framework. You do not have to be a seasoned veteran to use Cocos2D, and the framework makes it very easy to create high quality games. At the time of this writing, version 8.2 of the Cocos2D-iPhone framework was the most stable version, and hence it provides the basis for this tutorial.
There are several features available within OpenFeint in terms of score and event management. Beyond just tracking high scores, the developer can establish goals such that the player can earn achievements or even initiate online challenges. For this tutorial, the focus will be to simply enable an online leaderboard. The player will be able to track their own progress as well as compare their scores against other players via a global leaderboard.
There is also the ability to enable a chat function between players. While I have not tried it, I have been told by other developers that by enabling this feature you’re required to assign a mature rating. The mentality is that unrestricted chat within a game could expose minors to unscrupulous users and content.
Specifically, the OpenFeint capabilities consist of the following features:
Access to the OpenFeint code is done through the OpenFeint developer portal, and there is no charge to enroll in the developer program. Visit http://www.openfeint.com/ to sign-up for access.
Once authenticated with the portal, you’ll have access to the developer home page and will be able to download the OpenFeint SDK.
When enabling an application to use the OpenFeint service, you register it within the developer portal. Selecting the green plus button at the top of the page allows you to start this process. In this example we’ll add a test application, My Crazy App, so that you can see the various screens. Yet, the specific code examples shown later on will reflect the integration process with one of my OpenFeint enabled games, Balloon-Boy.
The following screen capture shows the entry of the application details to register the application.
After selecting submit, the application is given a Client Application ID, Product Key, and Product Secret. As we’ll later see, these values are needed when initializing OpenFeint within our application. Keep them handy as we’ll need them when it comes time to add the respective OpenFeint code to the application.
The following shows a closer look at the application’s specific product key and secret. They are unique for each registered application and are used to identify the specific application when communicating with the OpenFeint servers.
The following shows the creation of the game’s leaderboard. It’s a straight forward process initiated by selecting ‘Basic Features’ and then Leaderboards.
After selecting submit, we see that our leaderboard has been created. It is important to note the leaderboard ID as we’ll need this value later on when attempting to post user’s scores to the board. The value identifies the specific leaderboard and is a required element for the code that is executed when we initiate onlinescore updates.
Now that we’ve enrolled in the OpenFeint program, downloaded the SDK, and created an entry for our application, it is time to start the integrating process within our Cocos2D-iPhone application.
There are some preliminary steps before inclusion of code within your class files. If you’re upgrading from a prior version, the process is relatively straight forward. You simply delete the old OpenFeint folder from your XCode project and need to ensure that you add some additional frameworks, which will be detailed in the following section. Note: it is also important that you go into your project’s directory and also delete both the OpenFeint and build directories.
Let’s review the the OpenFeint README.txt for information on integration of the application.
If you’ve downloaded and extracted the OpenFeint SDK, you’re ready to begin the process. For step 4 of the README file, we’re to drop the unzipped OpenFeint folder into our XCode project. And since the game is landscape only, we’ll remove the Portrait folder found under the Resources directory as suggested for step 5. The following shows the inclusion of the OpenFeint folder within our XCode project.
Continuing on with Step 6, we right click on our project icon within XCode and select Get Info. In looking at the build tab, we added the Linker Flags the value -ObjC as well as selected ‘Call C++ Default Ctors/Dtors in Objective-C’. These are shown in the following screen capture.
For step 7, the README.txt notes the following frameworks that must be included within the project. And if you’re like me, I can never remember the all too convenient path so here it is for reference. Right click on frameworks and add existing framework. Navigate to:
/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulatorx.y.z.sdk/System/Library/Frameworks/<select framework>
Here are the frameworks you’ll need to ensure you’ve included in your XCode project.
- Foundation
- UIKit
- CoreGraphics
- QuartzCore
- Security
- SystemConfiguration
- libsql3.0.dylib (located in (iPhoneSDK Folder)/usr/lib/)
- CFNetwork
- CoreLocation
- MapKit (if building with SDK 3.0 or newer)
And here we see the frameworks that have been added to the XCode project.
For the latest release of OpenFeint, if you have set your ‘iPhoneOS Deployment Target’ to any version before 3.0 you must weak link some libraries. Select ‘Targets’ in the Groups & Files pane.
- Right click your target and select Get Info.
- Select the ‘General’ tab.
- Under ‘Linked Libraries’ change the following libraries from ‘Required’ to ‘Weak’
- UIKit
- MapKit
For my project I’m not building for lesser versions, which from what I’ve heard though does exclude a sizable base of users.
Finally, in step 9 of the README.txt, we need to add the following line to our prefix header:
#import "OpenFeintPrefix.pch"
The following screen capture shows the quick update of the project’s prefix header.
At this point we now have the SDK integrated within our XCode project along with some necessary support requirements. Again, this tutorial covers the specific integration of OpenFeint with a Cocs2D-iPhone v8.2 based application. As with most application architectures, there will be various class files such as the application delegate, game scene, and menu scene.
Let’s now add the required OpenFeint code to our project’s AppDelegate.
Within the AppDelegate’s main file we’ll add various code elements ranging from importing other class headers to specific code needed within existing methods. For example, there’s specific OpenFeint code that should be added to applicationWillResignActive, applicationDidBecomeActive, and applicationWillTerminate. These methods can already be found in your Cocos2D application delegate, and we’ll be adding a line here or there to support integration with OpenFeint. The OpenFeint developer documentation details these requirements as it’s expected that you’re taking action based upon the application’s state, such as it shutting down.
Add the following import statements to your AppDelegate’s main file:
#import "OpenFeint.h" #import "SampleOFDelegate.h"
Now locate the respective methods within your AppDelegate’s main file, and add the lines identified for OpenFeint.
- (void)applicationWillResignActive:(UIApplication *)application {
[[SimpleAudioEngine sharedEngine] stopBackgroundMusic];
[[Director sharedDirector] pause];
[OpenFeint applicationWillResignActive]; // Add for OpenFeint
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[[Director sharedDirector] resume];
[OpenFeint applicationDidBecomeActive]; // Add for OpenFeint
}
- (void)applicationWillTerminate:(UIApplication *)application {
[[SimpleAudioEngine sharedEngine] stopBackgroundMusic];
[[Director sharedDirector] end];
[[NSUserDefaults standardUserDefaults] synchronize]; // Add for OpenFeint
}
Next we’ll create a class that will handle some crucial tasks whenever we call the OpenFeint leaderboard. At the time, I had based this on the included SampleOFDelegate files. Pay particular attention to the dashboardDidAppear and dashboardDidDisappear methods. You’ll see that we’re momentarily pausing the Cocos2D director and then re-enabling it once the dashboard disappears. This is a critical step cause otherwise it’s possible that input will be inconsistent or even not captured when the dashboard is displayed. But by pausing the director, we’re ensured that all user input is captured by the dashboard.
Create the following files within your XCode project.
SampleOFDelegate.h
// // SampleOFDelegate.h // Balloon-Boy // // Created by Tim Sills on 12/4/09. // #import "OpenFeintDelegate.h" @interface SampleOFDelegate : NSObject< OpenFeintDelegate > - (void)dashboardWillAppear; - (void)dashboardDidAppear; - (void)dashboardWillDisappear; - (void)dashboardDidDisappear; - (void)userLoggedIn:(NSString*)userId; - (BOOL)showCustomOpenFeintApprovalScreen; @end
SampleOFDelegate.m
// SampleOFDelegate.m
// Balloon-Boy
//
// Created by Tim Sills on 12/4/09.
//
#import "OpenFeint.h"
#import "SampleOFDelegate.h"
#import "cocos2d.h"
@implementation SampleOFDelegate
- (void)dashboardWillAppear
{
}
- (void)dashboardDidAppear
{
[[Director sharedDirector] pause];
[[Director sharedDirector] stopAnimation];
}
- (void)dashboardWillDisappear
{
}
- (void)dashboardDidDisappear
{
[[Director sharedDirector] resume];
[[Director sharedDirector] startAnimation];
}
- (void)userLoggedIn:(NSString*)userId
{
OFLog(@"New user logged in! Hello %@", [OpenFeint lastLoggedInUserName]);
}
- (BOOL)showCustomOpenFeintApprovalScreen
{
return NO;
}
@end
For my particular Cocos2D application, I have a splash scene that quickly shows the company logo, the Cocos2D logo, and then transitions to the game’s main menu. I initialize OpenFeint during this process just before loading the main menu. With that said, the header file for the splash scene class has the following code. We’re including the SampleOFDelegate class as well as declaring the ofDelegate variable. I’ve streamlined the content to only include the references to the OpenFeint code. I’ve left the reference to the menuScene method though as that’s where I perform the initialization.
// SplashScene.h
// Balloon-Boy
//
// Created by Tim Sills on 12/1/09.
//
#import <UIKit/UIKit.h>
#import "cocos2d.h"
@class SampleOFDelegate; // Add for OpenFeint
@interface SplashScene : Scene {
SampleOFDelegate *ofDelegate; // Add for OpenFeint
}
-(void)menuScene;
@end
For the main file of the splash scene class, we import the following header files:
#import "OpenFeint.h" #import "SampleOFDelegate.h"
Within my method that is called before transitioning to the main menu (menuScene), I initialize OpenFeint. It is here where we can set the orientation, disable chat, and provide our application specific values such as the product key. You might recall that these were provided when first registering the application within OpenFeint’s developer portal as shown in the following:
For the initialization process, we declare a dictionary that will include the details specific to our application. Where ever it is you want to perform the initialization within your application, add the following code.
NSDictionary* settings = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight], OpenFeintSettingDashboardOrientation, [NSNumber numberWithBool:YES], OpenFeintSettingDisableUserGeneratedContent, nil]; ofDelegate = [SampleOFDelegate new]; OFDelegatesContainer* delegates = [OFDelegatesContainer containerWithOpenFeintDelegate:ofDelegate]; [OpenFeint initializeWithProductKey:@"zGMPDEYldUia4j86uV1mA" andSecret:@"QMjb1n9dV4MVO09U05R56MUCeJf7VZHnKlQIvRKtk" andDisplayName:@"My Crazy App" andSettings:settings // see OpenFeintSettings.h andDelegates:delegates]; // see OFDelegatesContainer.h
For my particular application, once the initialization has been done, it then transitions to the main menu. If you’re already a registered user you’ll get the welcome back screen or if you’re a new user (or perhaps using a new device), you’ll have the opportunity to either login or register for a new account.
The following shows the OpenFeint screen that is seen when a new user or device is detected. The user can enable OpenFeint or alternatively indicate they don’t want these features right now.
Upon enabling OpenFeint, the application will recognize a device already associated with the user’s account and automatically log them in as shown in the following screen capture.
Additional features in the latest OpenFeint release now provide the ability to connect with your Twitter and FaceBook accounts as well as even share your location for geographic based scoring comparisons.
Once logged in, the user can easily review the scores for the various applications that use OpenFeint. In this case, we’re going to review the leaderboard for Balloon-Boy. The following shows the layout of my particular game’s main menu.
When a user selects the Scores option at the main menu, the following line of of code is executed within the called method. Take note of the text passed text value. This is the lD for our leaderboard that was assigned at the time of creation, which in this case is reflecting the value for the test application registered for this tutorial.
[OpenFeint launchDashboardWithHighscorePage:(NSString*)@"181963"];
The code is pretty self explanatory and launches the high score dashboard for our application. You also have the option of defaulting to other screens when initially launching the OpenFeint dashboard, so be sure to check the SDK for such details.
In the following screen capture, we see the various leaderboards tracked via OpenFeint. You might recall that this is what was enabled during the application registration process within OpenFeint’s developer portal. My application is very simplistic and simply tracks the user’s personal score and a global score. The following provides a view of the global leader board for the Balloon-Boy application.
As mentioned earlier, another neat feature available with the more recent OpenFeint version is the ability to share your location to identify other players in your general vicinity.
This all sounds great, but the next question is how do we post these scores to OpenFeint? The process is incredibly simple. For my Balloon-Boy game, after the user’s piloted balloon has had three impacts, the game is over. At this point I give the player the opportunity to play again, but when this method is initially called, I execute the following bit of code to post the user’s score. In particular, I have a variable named currentScore that contains the user’s accumulated score. The currentScore’s value is posted to the OpenFeint leaderboard. It is also important to note the leaderboard ID again. This is the same value given to us when we first created the leaderboard in the developer portal. The leaderboard details are provided again for reference in the following screen capture.
The leaderboard ID is used to identify the specific board for the application that’ll receive the value. The following shows the single line of code used to post the current score to the appropriate leaderboard for our application.
***************** 181963 is for the marathon leaderboard ************************* [OFHighScoreService setHighScore:currentScore forLeaderboard:@"181963" onSuccess:OFDelegate() onFailure:OFDelegate()];
The following screen capture shows in my application where the user is presented with the opportunity to either play again or return to the main menu. When this overlay is initially shown, there is a brief confirmation message shown at the bottom of the screen as the score is posted to the OpenFeint leaderboard. This is as a result of executing the single line of code noted above.
The integration process is nearly complete with only some minor additional changes required. In order to compile the OpenFeint C code, we have to change the extension all of our main class files from .m to .mm. Meaning, gameScene.m now becomes gameScene.mm. There’s no impact to the existing Objetive-C code, but if not done then there will be a lot of problems when attempting to compile the code otherwise.
Lastly, if you’re using a physics engine such as Chipmunk, there will also be errors at compile time due to the static void method. In particular, you’ll receive an error like request for member shape in something not structure or union. This is an issue of simply needing to cast the shape data and is solved by adding (Sprite *) as shown in the following.
static void
eachShape(void *ptr, void* unused)
{
cpShape *shape = (cpShape*) ptr;
Sprite *sprite = (Sprite *)shape->data;
if( sprite ) {
cpBody *body = shape->body;
[sprite setPosition: cpv( body->p.x, body->p.y)];
[sprite setRotation: (float) CC_RADIANS_TO_DEGREES( -body->a )];
}
}
This concludes the integration of OpenFeint with a Cocos2D-iPhone application tutorial. Hopefully the process went smoothly and you’re now updating scores to an online leaderboard. Feel free to contact me regarding any feedback or content errors. Also be sure to check OpenFeint’s own knowledgebase and support forums for additional information.

























It’s best article – very-very helpful!
Thanks to Author and regard !
A really well written article, thanks ! Will definitely try this out.
[...] Tutorials: OpenFeint and Cocos2D iPhone Tutorial Admob and Cocos2D iPhone [...]
Awesome tutorial – thanks for sharing! I’ll definitely try this out when it gets time for me to implement leaderboards into my game.
Thanks Ray, and equally so you have some great tutorials on your site.
everyone- visit his site for some great Cocos2D and Box2D coding examples at:
raywenderlich.com
Thanks Ray its a very helpful tutorial.
but i am facing some problem.
I have downloaded the balloon-boy app.
in this app score i can see a global score and a personal score bt when i m trying integrate openfeint using ur tutorial i cant see the personal score.
is there any way to see personal local score.
Waiting for ur reply.
Thanks in advance
Best Regards
Evana
Evana,
I had noticed also that the individual leaderboard seemed to be missing from within the latest OF SDK implementation. In an earlier version of the SDK it seemed to handle it on its own cause I did not do anything in particular to enable it within the code or via OF’s developer portal. And we can see from this screen shot of an earlier version the tab for personal scores:
I had actually posted this question within their developer forum a few days ago and just checked but unfortunately there hasn’t been a response yet. I’ll post something as soon as I can get an update.
Thanks Tim waiting for your post soon.
Thank you very much for this tutorial!!!!!
Very complete and everything works like a charm.
I’m implementing an update of my game (Captain Glyph: http://itunes.apple.com/us/app/captain-glyph/id366277642?mt=8 ) as soon as I do some testing.
By the way, how do you close the dashboard??? The little x up right is not working.
Thanks again!!!!
@Andoni,
I had the same problem when initially implementing OF…you absolutely need to make sure and pause the Cocos2D director.
Review the SampleOFDelegate.m as noted above and be sure you’ve added the following for when the dashboard appears:
- (void)dashboardDidAppear
{
[[Director sharedDirector] pause];
[[Director sharedDirector] stopAnimation];
}
Be sure to also resume Director when the dashboard disappears.
Hi
thanks for the good instructions.
But I have the same problem.
I can not close the open Feint window.
The little x up right is not working.
- (void)dashboardDidAppear
{
printf(“dashboardDidAppear \n”);
[[Director sharedDirector] pause];
[[Director sharedDirector] stopAnimation];
}
the function is called correctly // printf….
but the little X up right is not working.
open Feint v2.4.8 and cocos2d v0.8.0 – beta
can someone help?
Thanks
I found the solution:
http://openfeint.com/developers/forum/showthread.php?70-Can-t-close-dashboard&highlight=simulator
For the simulator, you must hold down the option key and press the X
Hi
thanks for this great article. I implemented open Feint in my game very fast using the instructions in this article. I have an issue with achievements. My game is unlocking the achievements but achievements are not visible on dashborad. There are only three options there on dashboard: leaderboards , Fan Club and who’s Playing. How to add achievements on the dashboard??
Hi
I resolved the achievements issue. Now there is another problem. If the user clicks the welcome back notification of the open Feint in my game Layer it removes some of the chipmunk objects from the game layer. But i am facing this issue only in iPhone. On simulator game just pauses and resumes after pressing the open Feint X.
Hey great tutorial! It helped me alot!
Openfeint is really easy to integrate!
Hi, How Can I know that the Openfeint is Enabled or Not? I mean whether any user is already loging in or not? Please Let me know
Hey Sunil,
When you start seeing scores posted to the leader board you’ll know that people are using the game and have enabled OF. If they’re not enabling OF when starting to play then you won’t have the visibility through OF. But other people have enabled features in their game to reach back to an online server as a means to track when people are using their game. This is how they’ll often times see all of the illegal copies in use in comparison to the paid copies they know should be out there.
thanks very much, just wonder if there are some sample codes project to give some demo learning ?
and when I check the latest openfeint (2.5) , seems like something are different now.
Thanks For your Prompt Reply But I need to ask that how to know Programmatically that user has login the Step of OpenFeint or they just Skipped. Is there any Event or Argument I get like Bool that user has set up his Account or Not ?
Please let me Know ASAP. I am in middle of Development. Just this thing is left other then that its over…..
Hello, how to make the “welcome back…” bar appear from top of the screen instead from the bottom?
Thanks!
Forrest- yes, things are rapidly changing. I only just recently looked to update some of my code to support the newer OF SDK. I’m planning on updating the tutorial shortly regarding the slight changes.
Sunil- from an OF perspective I’m not sure you’ll know that they skipped since there’d be no communications back to OF. At this point this is where people are reaching back to their own server through their own code to see if an app is online and being used, which is typically done to track piracy (not that it’ll stop it though, but at least show you all of the installations out there).
Hao- I took a look at the OF settings and didn’t see anything that would allow you to do specific placement. I saw where you asked the question on OF’s own forums and unfortunately it doesn’t look like they responded with anything either. Maybe an upcoming release will allow you set the specific location.