Supercharge Announcements with Custom UI

Introduction

Have you ever wanted a way to communicate directly with your players inside your game without pushing an update? OpenFeint announcements allow you to do just that! Through the OpenFeint Developer Dashboard you can manage posts that will be seen by your player base, and by implementing a custom display you can increase the impact of your message. Through custom announcements, developers have been able to increase player engagement and boost the sales/chart position of their titles.

On the left hand side is the default announcements view. Never seen it? Its buried in the Fan Club section of the OpenFeint dashboard.

Ingredients List:

OFAnnouncement.h OFBadgeView.h Developer Dashboard Custom UI elements Announcement Text

Time to Implement:

Approximately 2 hours plus the time to customize your own UI

What will this help me with?

Connecting with my player community Promoting my games and increasing sales

Recipe:

Begin by reading the following header files: OFAnnouncement.h and OFBadgeView.h. The first header provides access to the announcement data stored on OpenFeint servers. The second header is a subclass of UIView that provides a simple way to display numbered badges.

Create an announcement in the Developer Dashboard under FEATURES -> ANNOUNCEMENTS -> ADD GAME ANNOUNCEMENT Note: you can only create announcements for applications that have been approved and enabled by OpenFeint. If you need an approval for testing, please note it in your comments when submitting to us.

Build the OpenFeint sample code utilizing your own product key and secret provided in the developer dashboard. A custom UI for displaying announcements is implemented in SampleAnnouncementController.mm and its corresponding .h and .xib files. This example demonstrates the use of the OFAnnouncement.h API for fetching announcement data from the server.

Run the sample app. Accept an OpenFeint ID when the OpenFeint welcome screen appears. When the app returns to its main view, scroll to the Explore Announcements button and click on it. Youll see the announcement you created.

SampleAnnouncementController implements its custom UI through standard UIKit elements laid out in InterfaceBuilder. Regardless of whether your UI uses UIKit or not, you will fetch the announcement data through the OFAnnouncement.h API in the same way.

Notice that SampleAnnouncementController.h adopts two protocols, namely OFCallbackable and OFAnnouncementDelegate. Your custom controller should also adopt these protocols.

@interface SampleAnnouncementController : UIViewController

Notice that SampleAnnouncementController.mm calls [OFAnnouncement setDelegate:self] from the viewDidAppear method. You should do the same for your custom controller to let it handle delegate methods of the OFAnnouncementDelegate protocol. You should also disable this delegation in viewWillDisappear by calling [OFAnnouncement setDelegate:nil].

The downloading of the announcement data is an asynchronous request initiated by [OFAnnouncement downloadAnnouncementsAndSortBy:EAnnouncementSortType_CREATION_DATE]. It returns a request handle that will be non-nil if the request was initiated. This is also demonstrated in the viewDidAppear method of SampleAnnouncementController.mm.

If the call to downloadAnnouncementsAndSortBy returned a non-nil request handle, the asynchronous result will arrive as a call to the didDownloadAnnouncementsAppAnnouncements delegate if the transaction is successful. If the transaction is not successful, such as due to a loss of network connectivity, the didFailDownloadAnnouncements delegate method will be called instead. The interesting part is demonstrated in the success delegate of SampleAnnouncementController as shown below:

- (void)didDownloadAnnouncementsAppAnnouncements:(NSArray*)appAnnouncements devAnnouncements:
    (NSArray*)devAnnouncements;   {
      OFSafeRelease(appAnnouncementList);
      OFSafeRelease(devAnnouncementList);
      appAnnouncementList = [appAnnouncements retain];
      devAnnouncementList = [devAnnouncements retain];
      [self setAnnouncementType: AnnouncementType_App];
    }

Note that appAnnouncementList and devAnnouncementList are defined as static variables at the top of the file to hold the downloaded content:

static NSArray *appAnnouncementList = nil;
static NSArray *devAnnouncementList = nil;

Each announcement may be associated with a number of posts which are also fetched asynchronously. Following a pattern similar to fetching the announcements, the posts associated with a specific announcement can be fetched by the following call:

OFRequestHandle* handle = ? [curAnnouncement getPosts];

and the asynchronous result will arrive as a call to protocol delegate methods didGetPosts or didFailGetPostsOFAnnouncement. The interesting part demonstrated in didGetPosts is as follows:

- (void)didGetPosts\:(NSArray*)posts OFAnnouncement\:(OFAnnouncement*)announcement {
    NSInteger postCount = [posts count];
     if (postCount > 0) {
       if ((postIndex < 0) || (postCount <= postIndex)){
         postIndex = 0;
       }
       OFForumPost *curPost = (OFForumPost*) [posts objectAtIndex:postIndex];
       postText.text = [NSString stringWithString:curPost.body];
       postIndexText.text = [NSString stringWithFormat: @"%d", postIndex + 1];
     }
     else{ postText.text = @"";
  }
  postCountText.text = [NSString stringWithFormat: @"%d", postCount];
}

If you want to place a badge on your app icon you can use the setApplicationIconBadgeNumber method from the iOS SDK. For example, the following line will place the value 5 in a badge:

[[UIApplication sharedApplication] setApplicationIconBadgeNumber:5];

Its up to you to decide what this badge number will mean for your application. You can choose whether to just put the unread announcement count here or perhaps include pending friend requests and unviewed challenges using the return value from the following method to sum up all of the badge counts represented in the player dashboard interface.

[OFCurrentUser OpenFeintBadgeCount];

Whats Next?

Now that youve created a custom announcement system, how can you best utilize the feature? Here are some suggestions on updates that you can provide to your player base: Fixed a bug and just waiting impatiently for Apples approval? Push a note to your users that youre aware of the bug and are just waiting for the App Store to update. Promote contests, Facebook / Twitter accounts, and other ways that you talk to your player base. Announce new games and in-app purchases are coming soon and provide links to preview videos, web sites, etc. Help generate buzz for your new title and announce on launch day to give yourself the best shot at moving up the App Store charts. Send a notification to a specific game, or use the advanced features to send a notification into all your OpenFeint-enabled games. Dont overdo it. Remember that the main reason that players are launching your game is to play, not to read your (super witty) announcements. Still, it can be a very powerful mechanism to reach out to the people who have downloaded your app and build a relationship with them.