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.
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.
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:
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.
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.
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.
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 |
|
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
|
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];
}
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
|
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:
|
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
- Purchases of Items with Real Currency
- Purchases of Items with In-Game 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];
//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];
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.
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];
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];
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.
|
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
|
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];
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"];
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.
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>
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.
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 aweak
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 callstart
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
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
- Event Driven Frame - Open the Store for instance, when the player is running low on premium currency
- Event Driven Frame - Level Completion
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:
//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
}
}
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.
//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"
}
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:
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
}
}
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];
}
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.
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];
}
If you have any questions or issues, please contact [email protected].
- 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
- Support for video ads
- Capture advertising tracking information
- Renamed method in PlaynomicsMessaging.h from "initFrameWithId" to "createFrameWithId"
- Minor bug fixes
- Support for push notifications
- Minor bug fixes
- Support for internal messaging
- Added milestone module
- Support for new iOS hardware, iPhone 5s
- 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.
support for iOS version 4.x
- Improved crash protection
- Ability to run integrated app on the iOS simulator
- Minor tweaks to improve connection to server
- First production release
View version tags here