Git Product home page Git Product logo

ios-sdk-playnomics's Introduction

Playnomics PlayRM iOS SDK Integration Guide

If you're new to PlayRM and/or don't have a PlayRM account and would like to get started using PlayRM please visit https://controlpanel.playnomics.com/signup to sign up. Soon after creating an account you will receive a registration confirmation email permitting you access to your PlayRM control panel.

Within the control panel, click the applications tab and add your game. Upon doing so, you will recieve an Application ID and an API KEY. These two components will enable you to begin the integration process.

Our integration has been optimized to be as straight forward and user friendly as possible. If you're feeling unsure or would like better understand the order the process before beginning integration, please take a moment to check out the getting started page. Here you can find an overview of our integration process, and platform specific features, to help you better understand the PlayRM integration process.

Note, this is SDK is intended for working with native iOS games built with Xcode, if you're using Unity and deploying your game to iOS, please refer to the PlayRM Unity SDK.

Considerations for Cross-Platform Games

If you want to deploy your game to multiple platforms (eg: iOS, Android, etc), you'll need to create a separate Playnomics Applications in the control panel. Each application must incorporate a separate <APPID> particular to that application. In addition, message frames and their respective creative uploads will be particular to that app in order to ensure that they are sized appropriately - proportionate to your game screen size.

Basic Integration

You can download the SDK by forking this repo or downloading the archived files. All of the necessary install files are in the build folder:

  • libplaynomics.a
  • PlaynomicsFrame.h
  • PlaynomicsMessaging.h
  • PlaynomicsSession.h

Then import the SDK files into your existing game through Xcode:

Interacting with PlayRM in Your Game

All session-related calls are made through class PlaynomicsSession while all messaging-related calls are made through a sharedInstance of class PlaynomicsMessaging. To work with any of these classes, you need to import the appropriate header file:

#import PlaynomicsSession.h

All public methods, except for messaging specific calls, return an enumeration PNAPIResult. The values for this enumeration are:

Enumeration Description
PNAPIResultSent The event has been sent to PlayRM.
PNAPIResultAlreadyStarted You've already started the session. [PlaynomicsSession startWithApplicationId] was called unnecessarily.
PNAPIResultStartNotCalled You didn't start the session. The SDK won't be able to report any data to the PlayRM RESTful API, until this has been done.
PNAPIResultFailUnkown An unknown exception occurred.

You always need to start a session before making any other SDK calls.

Starting a Player Session

To start collecting behavior data, you need to initialize the PlayRM session. In the class that implements AppDelegate, start the PlayRM Session in the didFinishLaunchingWithOptions method.

You can either provide a dynamic <USER-ID> to identify each player:

+ (PNAPIResult) startWithApplicationId:(signed long long) applicationId
                                userId: (NSString *) userId;

or have PlayRM, generate a best-effort unique-identifier for the player:

+ (PNAPIResult) startWithApplicationId:(signed long long) applicationId;

If you do choose to provide a <USER-ID>, this value should be persistent, anonymized, and unique to each player. This is typically discerned dynamically when a player starts the game. Some potential implementations:

  • An internal ID (such as a database auto-generated number).
  • A hash of the user's email address.

You cannot use the user's Facebook ID or any personally identifiable information (plain-text email, name, etc) for the <USER-ID>.

You MUST make the initialization call before working with any other PlayRM modules. You only need to call this method once.

#import "AppDelegate.h"
#import "PlaynomicsSession.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    const long long applicationId = <APPID>;

    [PlaynomicsSession setTestMode:YES];
    [PlaynomicsSession startWithApplicationId:applicationId];
    //other code to initialize the application below this
}

To track intensity, PlayRM needs to monitor touch events. We provide an implementation of the iOS UIApplication<UIApplicationDelegate>, which automatically captures these events. In the main.m file of your iOS application, you pass this class name into the UIApplicationMain method:

#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "PlaynomicsSession.h"

int main(int argc, char *argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, NSStringFromClass([PNApplication class]), NSStringFromClass([AppDelegate class]));
    }
}

If you already have your own implementation of UIApplication<UIApplicationDelegate> in main.m, just add the following code snippet to your class implementation:

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "PlaynomicsSession.h"

@implementation YourApplication
- (void) sendEvent: (UIEvent *) event {
    [super sendEvent:event];
    if (event.type == UIEventTypeTouches) {
        UITouch *touch = [event allTouches].anyObject;
        if (touch.phase == UITouchPhaseBegan) {
            [PlaynomicsSession onTouchDown: event];
        }
    }
}
@end

Congratulations! You've completed our basic integration. You will now be able to track engagement behaviors (having incorporated the Engagement Module) from the PlayRM dashboard. At this point we recomend that you use our integration validation tool to test your integration of our SDK in order insure that it has been properly incorporated in your game.

PlayRM is currently operating in test mode. Be sure you switch to production mode, by implementing the code call outlined in our Basic Integration before deploying your game on the web or in an app store.

Full Integration

If you're reading this it's likely that you've integrated our SDK and are interested in tailoring PlayRM to suit your particular segmentation needs.

The index on the right provides a holistic overview of the full integration process. From it, you can jump to specific points in this document depending on what you're looking to learn and do.

To clarify where you are in the timeline of our integration process, you've completed our basic integration. Doing so will enable you to track engagement behaviors from the PlayRM dashboard (having incorporated the Engagement Module). The following documentation will provides succint information on how to incorporate additional and more in-depth segmentation functionality by integrating any, or all of the following into your game:

  • User Info Module: - provides basic user information
  • Monetization Module: - tracks various monetization events and transactions
  • Virality Module: - tracks the social activities of users
  • Milestone Module: - tracks significant player events customized to your game

Along with integration instructions for our various modules, you will also find integration information pertaining to messaging frame setup, and push setup within this documentation.

Demographics and Install Attribution

After the SDK is loaded, the user info module may be called to collect basic demographic and acquisition information. This data is used to segment users based on how/where they were acquired and enables improved targeting with basic demographics, in addition to the behavioral data collected using other events.

Provide each user's information using this call:

+ (PNAPIResult) userInfoForType: (PNUserInfoType) type 
                        country: (NSString *) country 
                    subdivision: (NSString *) subdivision
                            sex: (PNUserInfoSex) sex
                       birthday: (NSDate *) birthday
                         source: (PNUserInfoSource) source 
                 sourceCampaign: (NSString *) sourceCampaign 
                    installTime: (NSDate *) installTime;

If any of the parameters are not available, you should pass nil.

Name Type Description
type PNUserInfoType There is currently only one option available for this: PNUserInfoTypeUpdate for userInfo updates.
country NSString * This has been deprecated. Just pass nil.
subdivision NSString * This has been deprecated. Just pass nil.
sex PNUserInfoSex
  • PNUserInfoSexMale
  • PNUserInfoSexFemale
  • PNUserInfoSexUnknown
birthday NSDate A birthday for the player.
sourceAsString NSString * Source of the user, such as "FacebookAds", "UserReferral", "Playnomics", etc. These are only suggestions, any 16-character or shorter string is acceptable.
sourceCampaign NSString * Any 16-character or shorter string to help identify specific campaigns
installTime NSDate * When the player originally installed the game.

This method is overloaded, with the ability to use an enum for the source

+ (PNAPIResult) userInfoForType: (PNUserInfoType) type 
                        country: (NSString *) country 
                    subdivision: (NSString *) subdivision
                            sex: (PNUserInfoSex) sex
                       birthday: (NSDate *) birthday
                 sourceAsString: (NSString *) source 
                 sourceCampaign: (NSString *) sourceCampaign 
                    installTime: (NSDate *) installTime;
Name Type Description
source PNUserInfoSource You can use a predefined enumeration of PNUserInfoSource
  • PNUserInfoSourceAdwords
  • PNUserInfoSourceDoubleClick
  • PNUserInfoSourceYahooAds
  • PNUserInfoSourceMSNAds
  • PNUserInfoSourceAOLAds
  • PNUserInfoSourceAdbrite
  • PNUserInfoSourceFacebookAds
  • PNUserInfoSourceGoogleSearch
  • PNUserInfoSourceYahooSearch
  • PNUserInfoSourceBingSearch
  • PNUserInfoSourceFacebookSearch
  • PNUserInfoSourceApplifier
  • PNUserInfoSourceAppStrip
  • PNUserInfoSourceVIPGamesNetwork
  • PNUserInfoSourceUserReferral
  • PNUserInfoSourceInterGame
  • PNUserInfoSourceOther

Since PlayRM uses the game client's IP address to determine geographic location, country and subdivision should be set to nil.

#import "AppDelegate.h"
#import "PlaynomicsSession.h"
@implementation AppDelegate

//...
//...
//...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    
    //after you initialize the PlayRM Sessions
    NSDate *installDate = nil;
    if(isNewUser){
        installDate = [NSDate date];
    }

    PNAPIResult result = [PlaynomicsSession 
                    userInfoForType: PNUserInfoTypeUpdate
                    country: nil
                    subdivision: nil
                    sex: PNUserInfoSexFemale
                    birthday: [[NSDate alloc] initWithString:@"1980-01-01"];
                    source: @"AppStore"
                    sourceCampaign: @"Facebook Ad"
                    installTime: installDate];
}

Monetization

PlayRM provides a flexible interface for tracking monetization events. This module should be called every time a player triggers a monetization event.

This event tracks users that have monetized and the amount they have spent in total, real currency:

  • FBC (Facebook Credits)
  • USD (US Dollars)

or an in-game, virtual currency.

This outlines how currencies are described in PlayRM iOS

Currency Currency Data Type PNCurrencyCategoryType
Real PNCurrencyType
    • PNCurrencyUSD: USD dollars
    • PNCurrencyFBC: Facebook Credits
The currencyCategory is PNCurrencyCategoryReal
Virutal An NSString * name, 16 characters or less. The currencyCategory is PNCurrencyCategoryVirtual
+ (PNAPIResult) transactionWithId: (signed long long) transactionId
                           itemId: (NSString *) itemId
                         quantity: (double) quantity
                             type: (PNTransactionType) type
                      otherUserId: (NSString *) otherUserId
                    currencyTypes: (NSArray *) currencyTypes
                   currencyValues: (NSArray *) currencyValues
               currencyCategories: (NSArray *) currencyCategories; 
Name Type Description
transactionId signed long long A unique identifier for this transaction. If you don't have a transaction ID from payments system, you can genenate large random number.
itemId NSString * If applicable, an identifier for the item. The identifier should be consistent.
quantity double If applicable, the number of items being purchased.
transactionType PNTransactionType The type of transaction occurring:
  • PNTransactionBuyItem: A purchase of virtual item. The quantity is added to the player's inventory
  • PNTransactionSellItem: A sale of a virtual item to another player. The item is removed from the player's inventory. Note: a sale of an item will result in two events with the same transactionId, one for the sale with type SellItem, and one for the receipt of that sale, with type BuyItem.
  • PNTransactionReturnItem: A return of a virtual item to the store. The item is removed from the player's inventory
  • PNTransactionBuyService: A purchase of a service, e.g., VIP membership
  • PNTransactionSellService: The sale of a service to another player
  • PNTransactionReturnService: The return of a service
  • PNTransactionCurrencyConvert: A conversion of currency from one form to another, usually in the form of real currency (e.g., US dollars) to virtual currency. If the type of a transaction is CurrencyConvert, then there should be at least 2 elements in the currencyTypes, currencyValues, and currencyCategories arrays
  • PNTransactionInitial: An initial allocation of currency and/or virtual items to a new player
  • PNTransactionFree: Free currency or item given to a player by the application
  • PNTransactionReward: Currency or virtual item given by the application as a reward for some action by the player
  • PNTransactionGiftSend: A virtual item sent from one player to another. Note: a virtual gift should result in two transaction events with the same transactionId, one with the type GiftSend, and another with the type GiftReceive
  • PNTransactionGiftReceive: A virtual good received by a player. See note for PNTransactionGiftSend type
otherUserId NSString * If applicable, the other user involved in the transaction. A contextual example is a player sending a gift to another player.
currencyTypes NSArray * An array of currencyTypes, type is either NSString * or PNCurrencyType.
currencyValues >NSArray * An array of currency values, type is a double.
currencyCategories >NSArray * An array of currency categories, type is PNCurrencyCategoryType.

An overload for transactionWithId with a single currencyType of PNCurrencyType.

+ (PNAPIResult) transactionWithId: (signed long long) transactionId
                           itemId: (NSString *) itemId
                         quantity: (double) quantity
                             type: (PNTransactionType) type
                      otherUserId: (NSString *) otherUserId
                     currencyType: (PNCurrencyType) currencyType
                    currencyValue: (double) currencyValue
                 currencyCategory: (PNCurrencyCategory) currencyCategory;

All arguments are the same as the previous method, except that the currencyType,currencyValue, and currencyCategory are singular. The currencyCategory is likely PNCurrencyCategoryReal.

An overload for transactionWithId with a single currencyTypeAsString of NSString *.

+ (PNAPIResult) transactionWithId: (signed long long) transactionId
                           itemId: (NSString *) itemId
                         quantity: (double) quantity
                             type: (PNTransactionType) type
                      otherUserId: (NSString *) otherUserId
             currencyTypeAsString: (NSString *) currencyType
                    currencyValue: (double) currencyValue
                 currencyCategory: (PNCurrencyCategory) currencyCategory;

All arguments are the same as the first method, except that the currencyTypeAsString,currencyValue, and currencyCategory are singular. The currencyCategory is likely PNCurrencyCategoryVirtual.

We highlight three common use-cases below.

Purchases of In-Game Currency with Real Currency

A very common monetization strategy is to incentivize players to purchase premium, in-game currency with real currency. PlayRM treats this like a currency exchange. This is one of the few cases where multiple currencies are used in a transaction (first implementation of transactionWithId. itemId, quantity, and otherUserId are left null.

//player purchases 500 MonsterBucks for 10 USD

NSMutableArray *currencyTypes = [NSMutableArray array];
NSMutableArray *currencyValues = [NSMutableArray array];
NSMutableArray *currencyCategories = [NSMutableArray array];

//notice that we're adding all data about each currency in order

//in-game currency
[currencyTypes addObject: @"MonsterBucks"];
[currencyValues addObject: [NSNumber numberWithDouble: 500]];
[currencyCategories addObject: [NSNumber numberWithInt: PNCurrencyCategoryVirtual]];

//real currency
[currencyTypes addObject: [NSNumber numberWithInt: PNCurrencyUSD]];
[currencyValues addObject: [NSNumber numberWithDouble: -10]];
[currencyCategories addObject: [NSNumber numberWithInt: PNCurrencyCategoryReal]];

PNAPIResult result = [PlaynomicsSession transactionWithId: transactionId 
                            itemId: nil 
                            quantity: 0
                            type: PNTransactionCurrencyConvert
                            otherUserId: nil
                            currencyTypes: currencyTypes
                            currencyValues: currencyValues
                            currencyCategories: currencyCategories];

Purchases of Items with Real Currency

//player purchases a "Monster Trap" for $.99 USD

NSString *trapItemId = @"Monster Trap";
double quantity = 1;
double price = .99;


PNAPIResult result = [PlaynomicsSession transactionWithId: transactionId 
                            itemId: trapItemId 
                            quantity: quantity
                            type: PNTransactionBuyItem
                            otherUserId: PNCurrencyUSD
                            currencyType: currencyTypes
                            currencyValue: price
                            currencyCategory: PNCurrencyCategoryReal];

Purchases of Items with Premium Currency

This event is used to segment monetized players (and potential future monetizers) by collecting information about how and when they spend their premium currency (an in-game currency that is primarily acquired using a real currency). This is one level of information deeper than the previous use-cases.

Currency Exchanges

This is a continuation on the first currency exchange example. It showcases how to track each purchase of in-game attention currency (non-premium virtual currency) paid for with a premium:

//In this hypothetical, Energy is an attention currency that is earned over the lifetime of the game. 
//They can also be purchased with the premium MonsterBucks that the player may have purchased earlier.

//player buys 100 Mana with 10 MonsterBucks

NSMutableArray *currencyTypes = [NSMutableArray array];
NSMutableArray *currencyValues = [NSMutableArray array];
NSMutableArray *currencyCategories = [NSMutableArray array];

//notice that we're adding all data about each currency in order
//and that both currencies are virtual

//attention currency data
[currencyTypes addObject: @"Mana"];
[currencyValues addObject: [NSNumber numberWithDouble: 100]];
[currencyCategories addObject: [NSNumber numberWithInt: PNCurrencyCategoryVirtual]];

//premium currency data
[currencyTypes addObject: @"MonsterBucks"];
[currencyValues addObject: [NSNumber numberWithDouble: -10]];
[currencyCategories addObject: [NSNumber numberWithInt: PNCurrencyCategoryVirtual]];

PNAPIResult result = [PlaynomicsSession transactionWithId: transactionId 
                            itemId: nil 
                            quantity: 0
                            type: PNTransactionCurrencyConvert
                            otherUserId: nil
                            currencyTypes: currencyTypes
                            currencyValues: currencyValues
                            currencyCategories: currencyCategories];

Item Purchases

This is a continuation on the first item purchase example, except with premium currency.

//player buys 20 light armor, for 5 MonsterBucks

double itemQuantity = 20;
NSSString *itemId = @"Light Armor";

NSString *premimumCurrency = @"MonsterBucks";
double premiumCost = 5;

[PNAPIResult result = transactionWithId: transactionId
                           itemId: itemId
                         quantity: itemQuantity
                             type: PNTransactionBuyItem
                      otherUserId: nil
             currencyTypeAsString: premimumCurrency
                    currencyValue: premiumCost
                 currencyCategory: PNCurrencyCategoryVirtual];

Invitations and Virality

The virality module allows you to track a single invitation from one player to another (e.g., inviting friends to join a game).

If multiple requests can be sent at the same time, a separate call should be made for each recipient.

+ (PNAPIResult) invitationSentWithId: (signed long long) invitationId
                     recipientUserId: (NSString *) recipientUserId
                    recipientAddress: (NSString *) recipientAddress
                              method: (NSString *) method;
Name Type Description
invitationId signed long long A unique 64-bit integer identifier for this invitation.
            If no identifier is available, this could be a hash/MD5/SHA1 of the sender's and neighbor's IDs concatenated. <strong>The resulting identifier can not be personally identifiable.</strong>
        </td>
    </tr>
    <tr>
        <td><code>recipientUserId</code></td>
        <td>NSString *</td>
        <td>This can be a hash/MD5/SHA1 of the recipient's Facebook ID, their Facebook 3rd Party ID or an internal ID. It cannot be a personally identifiable ID.</td>
    </tr>
    <tr>
        <td><code>recipientAddress</code></td>
        <td>NSString *</td>
        <td>
            An optional way to identify the recipient, for example the <strong>hashed email address</strong>. When using <code>recipientUserId</code> this can be <code>null</code>.
        </td>
    </tr>
    <tr>
        <td><code>method</code></td>
        <td>NSString *</td>
        <td>
            The method of the invitation request will include one of the following:
            <ul>
                <li>facebookRequest</li>
                <li>email</li>
                <li>twitter</li>
            </ul>
        </td>
    </tr>
</tbody>

You can then track each invitation response. IMPORTANT: you will need to pass the invitationId through the invitation link.

+ (PNAPIResult) invitationResponseWithId: (signed long long) invitationId
                         recipientUserId: (NSString *) recipientUserId
                            responseType: (PNResponseType) responseType;
Name Type Description
invitationId singed long long The ID of the corresponding invitationSent event.
recipientUserId NSString * The recipientUserID used in the corresponding invitationSent event.
responseType PNResponseType Currently the only response PlayRM tracks acceptance
  • PNResponseTypeAccepted

Example calls for a player's invitation and the recipient's acceptance:

int invitationId = 112345675;
NSString* recipientUserId = @"10000013";

PNAPIResult sentResult = [PlaynomicsSession invitationSentWithId: invitationId
                                    recipientUserId: recipientUserId
                                    recipientAddress: nil 
                                    method: nil];

//later on the recipient accepts the invitation

PNAPIResult responseResult = [PlaynomicsSession invitationResponseWithId: invitationId
                                    recipientUserId: recipientUserId
                                    responseType: PNResponseTypeAccepted];

Custom Event Tracking

Milestones may be defined in a number of ways. They may be defined at certain key gameplay points like, finishing a tutorial, or may they refer to other important milestones in a player's lifecycle. PlayRM, by default, supports up to five custom milestones. Players can be segmented based on when and how many times they have achieved a particular milestone.

Each time a player reaches a milestone, track it with this call:

+ (PNAPIResult) milestoneWithId: (signed long long) milestoneId
                        andName: (NSString *) milestoneName;
Name Type Description
milestoneId signed long long A unique 64-bit numeric identifier for this milestone occurrence.
andName NSString * The name of the milestone, which should be "CUSTOMn", where n is 1 through 5. The name is case-sensitive.

Example client-side calls for a player reaching a milestone, with generated IDs:

//when milestone CUSTOM1 is reached
int milestoneCustom1Id = arc4random();
[PlaynomicsSession milestoneWithId: milestoneCustom2Id andName: "CUSTOM1"];

Validate Integration

After configuring your selected PlayRM modules, you should verify your application's correct integration with the self-check validation service.

Simply visit the self-check page for your application: https://controlpanel.playnomics.com/validation/<APPID>

You can now see the most recent event data sent by the SDK, with any errors flagged. Visit the self-check validation guide for more information.

We strongly recommend running the self-check validator before deploying your newly integrated application to production.

Switch SDK to Production Mode

Once you have validated your integration, switch the SDK from test to production mode by simply setting the PlaynomicsSession's setTestMode field to NO (or by removing/commenting out the call entirely) in the initialization block:

//...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //...
    [PlaynomicsSession setTestMode:NO];
    [PlaynomicsSession startWithApplicationId:applicationId];
    //...
}

If you ever wish to test or troubleshoot your integration later on, simply set setTestMode back to YES and revisit the self-check validation tool for your application:

https://controlpanel.playnomics.com/validation/<APPID>

Messaging Integration

This guide assumes you're already familiar with the concept of frames and messaging, and that you have all of the relevant frames setup for your application.

If you are new to PlayRM's messaging feature, please refer to integration documentation.

Once you have all of your frames created with their associated <PLAYRM-FRAME-ID>s, you can start the integration process.

SDK Integration

To work with, the messaging you'll need to import the appropriate header files into your UIViewController header file.

#import <UIKit/UIKit.h>
#import "PlaynomicsSession.h"
#import "PlaynomicsFrame.h"
#import "PlaynomicsMessaging.h"

@interface ViewController : UIViewController <UITextFieldDelegate>
{
    @private
    PlaynomicsFrame frame;
}

Then you need to obtain a reference to the PlaynomicsMessaging singleton:

PlaynomicsMessaging *messaging = [PlaynomicsMessaging sharedInstance];

Loading frames through the SDK:

- (PlaynomicsFrame *) createFrameWithId:(NSString *)frameId;
Name Type Description
frameId NSString* Unique identifier for the frame, the <PLAYRM-FRAME-ID>

Optionally, associate a class that can response to PNFrameDelegate protocol, to process rich data callbacks. See Using Rich Data Callbacks for more information.

- (PlaynomicsFrame *)createFrameWithId:(NSString*)frameId frameDelegate: (id<PNFrameDelegate>)frameDelegate;
Name Type Description
frameId NSString* Unique identifier for the frame, the <PLAYRM-FRAME-ID>
frameDelegate id<PNFrameDelegate> Processes rich data callbacks, see Using Rich Data Callbacks

If you are not using ARC, keep in mind that:

  • You do not need to release the PlaynomicsFrame object. The PlayRM SDK will automatically release the frame when it is closed.

  • You do need to release PNFrameDelegate. PlayRM only stores a weak reference to the delegate to avoid strong reference cycles.

  • Frames are loaded asynchronously to keep your game responsive. The createFrameWithId call begins the frame loading process. However, until you call start on the frame, the frame will not be drawn in the UI. This gives you control over when a frame will appear. Frames are destroyed on a ViewController transition or when closed.

In the example below, we initialize the frame when view is visible and then show it in another event delegate.

In practice, a frame can be loaded in a variety of ways.

#import "ViewController.h"

@implementation ViewController{
    PlaynomicsFrame* _frame;
}

- (void)viewDidLoad{
    PlaynomicsMessaging *messaging = [PlaynomicsMessaging sharedInstance];
    _frame = [messaging createFrameWithId: @"<PLAY-FRAME-ID>"];
}

-void someOtherEvent{
    [_frame start];
}
@end

Using Rich Data Callbacks

Depending on your configuration, a variety of actions can take place when a frame's message is pressed or clicked:

  • Redirect the player to a web URL in Safari
  • Firing a Rich Data callback in your game
  • Or in the simplest case, just close, provided that the Close Button has been configured correctly.

Rich Data is a JSON message that you associate with your message creative. When the player presses the message, the PlayRM SDK bubbles-up the associated JSON object to an object that can respond to the protocol, PNFrameDelegate, associated with the frame.

@protocol PNFrameDelegate <NSObject>
@required
    -(void) onClick: (NSDictionary*) jsonData;
@end

The actual contents of your message can be delayed until the time of the messaging campaign configuration. However, the structure of your message needs to be decided before you can process it in your game.

The Rich Data callback will not fire if the Close button is pressed.

Here are three common use cases for frames and a messaging campaigns

Game Start Frame

In this use-case, we want to configure a frame that is always shown to players when they start playing a new game. The message shown to the player may change based on the desired segments:

Segment Priority Callback Behavior Creative
At-Risk 1st In this case, we're worried once-active players are now in danger of leaving the game. We might offer them 50 MonsterBucks to bring them back.
Lapsed 7 or more days 2nd In this case, we want to thank the player for coming back and incentivize these lapsed players to continue doing so. We might offer them 10 MonsterBucks to increase their engagement and loyalty.
Default - players who don't fall into either segment. 3rd In this case, we can offer a special item to them for returning to the grame.
//AwardFrameDelegate.h

#import <Foundation/Foundation.h>
#import "PlaynomicsMessaging.h"
@interface AwardFrameDelegate : NSObject<PNFrameDelegate>
@end

//AwardFrameDelegate.m

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "AwardFrameDelegate.h"
#import "Inventory.h"

@implementation AwardFrameDelegate
- (void)onClick:(NSDictionary *)jsonData{
    if([data objectForKey: @"type"] != (id)[NSNull null] &&
         [[data objectForKey:@"type"] isEqualToString: @"award"]){
        
        if([data objectForKey: @"award"] != (id)[NSNull null]){
            NSDictionary* award = [data objectForKey: @"award"];
            
            NSString* item = [award objectForKey: @"item"];
            NSNumber* quantity = [award objectForKey: @"quantity"];

            //call your own inventory object
            [[Inventory sharedInstanced] addItem:item andQuantity: quanity];
        }
    }
}
@end

And then attaching this AwardFrameDelegate class to the frame shown in the first game scene:

@implementation GameViewController{
    AwardFrameDelegate* _awardDelegate;
    PlaynomicsFrame* _frame;
}
-(void) viewDidLoad{
    PlaynomicsMessaging* messaging = [PlaynomicsMessaging sharedInstance];
    _awardDelegate = [[AwardFrameDelegate alloc] init];
    _frame = [messaging createFrameWithId : frameId frameDelegate : _awardDelegate];
    [_frame start];
}

-(void) dealloc{
    //make sure to release the delegate, if you are not using ARC
    [_awardDelegate release];
    [super dealloc];
}
@end

The related messages would be configured in the Control Panel to use this callback by placing this in the Target Data for each message:

Grant 10 Monster Bucks

{
    "type" : "award",
    "award" : 
    {
        "item" : "MonsterBucks",
        "quantity" : 10
    }
}

Grant 50 Monster Bucks

{
    "type" : "award",
    "award" : 
    {
        "item" : "MonsterBucks",
        "quantity" : 50
    }
}

Grant Bazooka

{
    "type" : "award",
    "award" :
    {
        "item" : "Bazooka",
        "quantity" : 1
    }
}

Event Driven Frame - Open the Store

An advantage of a dynamic frames is that they can be triggered by in-game events. For each in-game event you would configure a separate frame. While segmentation may be helpful in deciding what message you show, it may be sufficient to show the same message to all players.

In particular one event, for examle, a player may deplete their premium currency and you want to remind them that they can re-up through your store. In this context, we display the same message to all players.

Segment Priority Callback Behavior Creative
Default - all players, because this message is intended for anyone playing the game. 1st You notice that the player's in-game, premium currency drops below a certain threshold, now you can prompt them to re-up with this message.
//StoreFrameDelegate.h

#import <Foundation/Foundation.h>
#import "PlaynomicsMessaging.h"
@interface StoreFrameDelegate : NSObject<PNFrameDelegate>
@end

//StoreFrameDelegate.m

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "StoreFrameDelegate.h"
#import "Inventory.h"

@implementation StoreFrameDelegate
- (void)onClick:(NSDictionary *)jsonData{
    if([data objectForKey: @"type"] != (id)[NSNull null] && 
        [[data objectForKey:@"type"] isEqualToString: @"action"]){
        
        if([data objectForKey: @"action"] != (id)[NSNull null] && 
            [[data objectForKey:@"type"] isEqualToString: @"openStore"]){
            
            [[Store sharedInstance] open];
        
        }
    }
}
@end

The Default message would be configured in the Control Panel to use this callback by placing this in the Target Data for the message :

{
    "type" : "action",
    "action" : "openStore"
}

Event Driven Frame - Level Completion

In the following example, we wish to generate third-party revenue from players unlikely to monetize by showing them a segmented message after completing a level or challenge:

Segment Priority Callback Behavior Creative
Non-monetizers, in their 5th day of game play 1st Show them a 3rd party ad, because they are unlikely to monetize.
Default: everyone else 2nd You simply congratulate them on completing the level and grant them some attention currency, "Mana" for completeing the level.

This another continuation on the AwardFrameDelegate, with some different data. The related messages would be configured in the Control Panel:

  • Non-monetizers, in their 5th day of game play, a Target URL: HTTP URL for Third Party Ad
  • Default, Target Data:
{
    "type" : "award",
    "award" :
    {
        "item" : "Mana",
        "quantity" : 20
    }
}

Push Notifications

Registering for PlayRM Push Messaging

To get started with PlayRM Push Messaging, your app will need to register with Apple to receive push notifications. Do this by calling the registerForRemoteNotificationTypes method on UIApplication.

@implementation AppDelegate

//...

- (BOOL)application:(UIApplication *)application 
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    const long long applicationId = <APPID>;
    [PlaynomicsSession startWithApplicationId:applicationId];

    //enable notifications
    UIApplication *app = [UIApplication sharedApplication];
    [app registerForRemoteNotificationTypes: (UIRemoteNotificationTypeBadge 
        | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
    //...
}

Once the player, authorizes push notifications from your app, you need to provide Playnomics with player's device token

@implementation AppDelegate

//...

-(void)application:(UIApplication *)application 
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
   [PlaynomicsSession enablePushNotificationsWithToken:deviceToken];
}

Push Messaging Impression and Click Tracking

There are 3 situations in which an iOS device can receive a Push Notification

Sitatuation Push Message Shown? Delegate Handler
App is not running Yes didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
App is running in the background didReceiveRemoteNotification:(NSDictionary*)userInfo
App is running in the foreground No

The first situation is automatically handled by the Playnomics SDK. The other two situations, however, need to be implemented in the didReceiveRemoteNotification method:

-(void) application:(UIApplication *)application
    didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    NSMutableDictionary *payload = [userInfo mutableCopy];
    [PlaynomicsSession pushNotificationsWithPayload:payload];
    [payload release];
}

By default, iOS does not show push notifications when your app is already in the foreground. Consequently, PlayRM does NOT track these push notifications as impressions nor clicks. However, if you do circumvent this default behavior and show the Push Notification when the app is in the foreground, you can override this functionality by adding the following line of code in the didReceiveRemoteNotification method:

    [payload setObject:[NSNumber numberWithBool:NO] forKey:@"pushIgnored"];

This will allow each push notification to be treated as a click even if the app is in the foreground.

Clearing Push Badge Numbers

When you send push notifications, you can configure a badge number that will be set on your application icon in the home screen. When you send push notifications, you can configure a badge number that will be set on your application. iOS defers the responsibility of resetting the badge number to the developer.

To do this, insert this code snippet in the applicationWillResignActive method of your UIAppDelegate

- (void)applicationWillResignActive:(UIApplication *)application {
    [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
}

Support Issues

If you have any questions or issues, please contact [email protected].

Change Log

Version 9

  • Adding support for Rich Data Callbacks
  • Targeting the arm7, arm7s, i386 CPU Arcitectures
  • Now compatible with iOS 5 and above
  • Supporting touch events for Cocos2DX

Version 8.2

  • Support for video ads
  • Capture advertising tracking information

Version 8.1.1

  • Renamed method in PlaynomicsMessaging.h from "initFrameWithId" to "createFrameWithId"
  • Minor bug fixes

Version 8.1

  • Support for push notifications
  • Minor bug fixes

Version 8

  • Support for internal messaging
  • Added milestone module

Version 7

  • Support for new iOS hardware, iPhone 5s

Version 6

  • Improved dual support for iOS4 and iOS5+ utilizing best methods depending on runtime version
  • This build is a courtesy build provided for debugging for an unreproducible customer-reported crash that was unrelated to PlayRM code.

Version 4

support for iOS version 4.x

Version 3

  • Improved crash protection
  • Ability to run integrated app on the iOS simulator
  • Minor tweaks to improve connection to server

Version 2

  • First production release

View version tags here

ios-sdk-playnomics's People

Contributors

jaredjenkins avatar jaymanzi avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.