Event Tracking
GameAnalytics features the following event types:
Event | Description |
---|---|
Ad | Ads shown and clicked, fill rate. |
Business | In-App Purchases supporting receipt validation on GA servers. |
Design | Submit custom event id’s. Useful for tracking metrics specifically needed for your game. |
Error | Submit exception stack traces or custom error messages. |
Health | Automatically submits health metrics related to your game such as FPS. |
Impression | Impression data from different ad networks |
Progression | Level attempts with Start, Fail & Complete event. |
Resource | Managing the flow of virtual currencies - like gems or lives |
Read more about events here
To send an event, remember to include the namespace GameAnalyticsSDK:
- Swift
- Objective-C
using GameAnalyticsSDK;
#import "GameAnalytics.h"
If you are new to GameAnalytics and our Events, please read our event guide here.
You will get the most benefit of GameAnalytics when understanding what and how to track.
Business Events
Business events are used to track in-game transactions using real money.
Configuration within the GameAnalytics tool is needed before receipt validation will be active. Please note that sandbox receipts will be flagged as valid. Read information about validation and requirements for different platforms here.
With Receipt
When an in-app purchase is completed call the following method.
- Swift
- Objective C
GameAnalytics.addBusinessEvent(withCurrency: "USD" amount:999 itemType:"Weapon" itemId:"SwordOfFire" cartType:"Menu" receipt:**receipt string**)
[GameAnalytics addBusinessEventWithCurrency:@"USD" amount:999 itemType:@"Weapon" itemId:@"SwordOfFire" cartType:@"Menu" receipt:**receipt string**];
Field | Type | Description | Example |
---|---|---|---|
currency | string | Currency code in ISO 4217 format: More info here. | USD |
amount | integer | Amount in cents. | 99 is 0.99$ |
itemType | string | The type / category of the item. | GoldPacks |
itemId | string | Specific item bought. | 1000GoldPack |
cartType | string | The game location of the purchase.Max 10 unique values. | EndOfLevel |
receipt | base64 string | The transaction receipt. Nil allowed. | nil |
If the receipt is nil (or is an invalid receipt) then the GA servers will register that amount as not validated.
In iOS objective-c you can get the receipt string like this:
- Swift
- Objective C
// Swift
let receiptUrl = Bundle.main.appStoreReceiptURL?.path;
if (!FileManager.default.fileExists(atPath: receiptUrl!)) {
var receiptData:Data?
do {
receiptData = try Data.init(contentsOf: Bundle.main.appStoreReceiptURL!)
}
catch {
print("ERROR: " + error.localizedDescription)
}
let receipt = receiptData?.base64EncodedString(options: Data.Base64EncodingOptions.init(rawValue: 0))
}
// Objective-C
NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
if (![[NSFileManager defaultManager] fileExistsAtPath:[receiptUrl path]]) {
NSData *receiptData = [NSData dataWithContentsOfURL:receiptUrl];
NSString *receipt = [receiptData base64EncodedStringWithOptions:0];
}
Auto-Fetch Receipt
Using an alternative method it is possible to let the SDK retrieve the receipt automatically when called directly after a successful in-app purchase.
- Swift
- Objective C
// Swift
GameAnalytics.addBusinessEvent(withCurrency: "USD" amount:999 itemType:"Weapon" itemId:"SwordOfFire" cartType:"Menu" autoFetchReceipt: true)
// Objective-C
[GameAnalytics addBusinessEventWithCurrency:@"USD" amount:999 itemType:@"Weapon" itemId:@"SwordOfFire" cartType:@"Menu" autoFetchReceipt: YES];
Price and currency format (ISO 4217 Format)
The amount is an integer with the price cent value. Basically this means multiplying the retrieved price with 100. Also the currency has to conform to the ISO 4217 format.
On iOS you usually implement IAP using the SKProduct
classes.
When initializing you would call the initWithProductIdentifiers
method using the SKProductsRequest
and get a list of products (valid and invalid). Also when completing the actual purchase you should have the SKProduct
object.
It is possible to use code frameworks that handle IAP flow (like soom.la
) and thereby get this information from that code. Make sure the price is in cents and that the currency strings are returned as required.
The code below demonstrates how to get price (cents) and currency from an SKProduct
object called skProduct
:
- Swift
- Objective C
// Swift
// price in cents + local currency
let numberFormatter = NumberFormatter.init()
numberFormatter.locale = skProduct?.priceLocale
let currency = numberFormatter.currencyCode
let priceInCents = skProduct?.price.multiplying(by: 100)
// Objective-C
// price in cents + local currency
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setLocale:skProduct.priceLocale];
NSString *currency = [numberFormatter currencyCode];
NSInteger priceInCents = [[skProduct.price decimalNumberByMultiplyingBy:[NSDecimalNumber decimalNumberWithString:@"100"]] intValue];
Custom Business Event Fields
It is possible to use a set of key-value pairs to add extra fields but it will only be available through raw data export.
- Swift
- Objective C
let fields = [String:Any];
fields["test"] = 100;
fields["test_2"] = "hello_world";
GameAnalytics.addBusinessEventWithCurrency("USD", 999, "Weapon", "SwordOfFire", "Menu", **receipt string**, fields);
NSMutableDictionary *fields = [[NSMutableDictionary alloc] init];
fields[@"test"] = @100;
fields[@"test_2"] = @"hello_world";
[GameAnalytics addBusinessEventWithCurrency:@"USD" amount:999 itemType:@"Weapon" itemId:@"SwordOfFire" cartType:@"Menu" receipt:**receipt string** customFields:fields];
For more information on custom event fields and raw data export go here.
For more information on Business Events go here.
Ad Events
The GameAnalytics ad event needs to be called when certain events happen for the implemented ad sdk’s. An ad sdk has callback methods activating code when certain things are activated (like ad show or ad clicked).
To use the ad event it is need to call the GameAnalytics SDK when these delegates are called.
The examples below describe how to implement this for the following ad-types.
- Rewarded video
- Interstitial
- Bannner
All code examples use AdMob SDK to showcase example usage. Other ad networks might differ in naming/structure, but the overall process should be applicable to all.
The ad SDK name argument for the ad event needs to be all lower-case with no spaces or underscore used. Here some examples of valid values to use for ad SDK names:
- admob
- unityads
- ironsource
- applovin
Rewarded Video
When you want to show an ad, it is either available or not. Call the ad event, when the ad is not available. We do not call ad event on show, as we call it on ad close later.
if ([[GADRewardBasedVideoAd sharedInstance] isReady]) {
[[GADRewardBasedVideoAd sharedInstance] presentFromRootViewController:self];
}
else
{
[GameAnalytics addAdEventWithAction:GAAdActionFailedShow adType:GAAdTypeRewardedVideo adSdkName:@"admob" adPlacement:@"[AD_PLACEMENT_OR_UNIT_ID]"];
}
Tracking time spent
If you want to track how much the user watched then start timer and keep track of current rewarded video ad when rewardBasedVideoAdDidOpen:(GADRewardBasedVideoAd *)rewardBasedVideoAd is called The following example is a method for how you could handle this.
- (void)rewardBasedVideoAdDidOpen:(GADRewardBasedVideoAd *)rewardBasedVideoAd {
// keep track of current rewarded video ad
currentRewardedVideoPlacement = @"[AD_PLACEMENT_OR_UNIT_ID]";
// start timer for this ad identifier
[GameAnalytics startTimer:currentRewardedVideoPlacement];
}
// when application goes to background (during the display of a rewarded video ad) then the timer needs to stop.
// therefore we need to call code in viewWillDisappear:(BOOL)animated and viewWillAppear:(BOOL)animated.
- (void)viewWillDisappear:(BOOL)animated {
if(currentRewardedVideoPlacement != nil)
{
[GameAnalytics pauseTimer:currentRewardedVideoPlacement];
}
}
- (void)viewWillAppear:(BOOL)animated {
if(currentRewardedVideoPlacement != nil)
{
[GameAnalytics resumeTimer:currentRewardedVideoPlacement];
}
}
Tracking ad rewards
If you want to track rewards from rewarded videos, then call an ad event in the method where rewards are registered.
For admob this method is called rewardBasedVideoAd
:(GADRewardBasedVideoAd *)rewardBasedVideoAd didRewardUserWithReward:(GADAdReward *)reward
and the following example is a method for how you could handle this.
(void)rewardBasedVideoAd:(GADRewardBasedVideoAd *)rewardBasedVideoAd
didRewardUserWithReward:(GADAdReward *)reward {
// send ad event - reward recieved
[GameAnalytics addAdEventWithAction:GAAdActionRewardReceived adType:GAAdTypeRewardedVideo adSdkName:@"admob" adPlacement:@"[AD_PLACEMENT_OR_UNIT_ID]"];
}
Interstitial
Showing an interstitial ad
When you want to show an ad, it is either available or not. Call the ad event, when the ad is not available.
if (self.interstitial.isReady) {
[self.interstitial presentFromRootViewController:self];
}
else
{
[GameAnalytics addAdEventWithAction:GAAdActionFailedShow adType:GAAdTypeInterstitial adSdkName:@"admob" adPlacement:@"[AD_PLACEMENT_OR_UNIT_ID]"];
}
For interstitials we track an event at the time it is being shown The following example is a method for how you could handle this:
- (void)interstitialWillPresentScreen:(GADInterstitial *)ad {
// send ad event
[GameAnalytics addAdEventWithAction:GAAdActionShow adType:GAAdTypeInterstitial adSdkName:@"admob" adPlacement:@"[AD_PLACEMENT_OR_UNIT_ID]"];
}
Tracking user clicks
Call event when interstitialWillLeaveApplication:(GADInterstitial *)ad
is called
The following example is a method for how you could handle this.
- (void)interstitialWillLeaveApplication:(GADInterstitial *)ad {
// send ad event
[GameAnalytics addAdEventWithAction:GAAdActionClicked adType:GAAdTypeInterstitial adSdkName:@"admob" adPlacement:@"[AD_PLACEMENT_OR_UNIT_ID]"];
}
Banner
Showing a banner ad
If the ad loads successfully send the following ad event when adViewDidReceiveAd:(GADBannerView *)adView
is called.
The following example is a method for how you could handle this.
- (void)adViewDidReceiveAd:(GADBannerView *)adView {
[GameAnalytics addAdEventWithAction:GAAdActionShow adType:GAAdTypeBanner adSdkName:@"admob" adPlacement:@"[AD_PLACEMENT_OR_UNIT_ID]"];
}
Tracking banner clicks
For admob the banner ad click is registered on the adViewWillLeaveApplication:(GADBannerView *)adView
callback. The following example is a method for how you could handle this.
- (void)adViewWillLeaveApplication:(GADBannerView *)adView {
// send ad event
[GameAnalytics addAdEventWithAction:GAAdActionClicked adType:GAAdTypeBanner adSdkName:@"admob" adPlacement:@"[AD_PLACEMENT_OR_UNIT_ID]"];
}
Custom Banner Event Fields
It is possible to use a set of key-value pairs to add extra fields but it will only be available through raw data export. Here is an example of how to use it:
- Swift
- Objective C
// Swift
let fields = [String:Any];
fields["test"] = 100;
fields["test_2"] = "hello_world";
GameAnalytics.addAdEventWithAction(GAAdActionClicked,GAAdTypeBanner, "admob", "[AD_PLACEMENT_OR_UNIT_ID]", fields)
// Objective-C
NSMutableDictionary *fields = [[NSMutableDictionary alloc] init];
fields[@"test"] = @100;
fields[@"test_2"] = @"hello_world";
[GameAnalytics addAdEventWithAction:GAAdActionClicked adType:GAAdTypeBanner adSdkName:@"admob" adPlacement:@"[AD_PLACEMENT_OR_UNIT_ID]" customFields:fields];
For more information about raw data export go here
Field | Type | Description | Example |
---|---|---|---|
adAction | enum | A defined enum for ad action (for example clicked). | GAAdActionClicked GAAdActionShow GAAdActionFailedShow GAAdActionRewardReceived |
adType | enum | A defined enum for ad type (for example interstitial). | GAAdTypeVideo GAAdTypeRewardedVideo GAAdTypePlayable GAAdTypeInterstitial GAAdTypeOfferWall GAAdTypeBanner |
adSdkName | string | Name of the Ad/Ad mediation SDK. | admob |
adPlacement | string | Identifier of ad in the game or the placement of it. | level_complete_ad |
duration | int | Optional. Only used for video ads to track how long the user watched the video for. | 10 |
noAdReason | enum | Optional. Used to track the reason for not being able to show an ad when needed (for example no fill). | GAAdErrorUnknown GAAdErrorOffline GAAdErrorNoFill GAAdErrorInternalError GAAdErrorInvalidRequest GAAdErrorUnableToPrecache |
For more information on Ad Events go here
Impression Events
- Fyber
- IronSource
- TopOn
- MAX
- Aequus
- AdMob
Fyber
To use impression data from Fyber add the following code inside the bannerDidShow, interstitialDidShow or rewardedDidShow depending on what ad types you use:
- (void)bannerDidShow:(FYBBannerAdView *)banner impressionData:(FYBImpressionData *)impressionData {
NSDictionary *impressionDataDict = [NSMutableDictionary dictionaryWithDictionary:@{}];
[impressionDataDict setObject:impressionData.advertiserDomain forKey:@"advertiserDomain"];
[impressionDataDict setObject:impressionData.campaignId forKey:@"campaignId"];
[impressionDataDict setObject:impressionData.creativeId forKey:@"creativeId"];
[impressionDataDict setObject:impressionData.countryCode forKey:@"countryCode"];
[impressionDataDict setObject:impressionData.currency forKey:@"currency"];
[impressionDataDict setObject:impressionData.impressionDepth forKey:@"impressionDepth"];
[impressionDataDict setObject:impressionData.demandSource forKey:@"demandSource"];
[impressionDataDict setObject:impressionData.demandSource forKey:@"impressionId"];
[impressionDataDict setObject:impressionData.networkInstanceId forKey:@"networkInstanceId"];
[impressionDataDict setObject:impressionData.priceAccuracy forKey:@"priceAccuracy"];
[impressionDataDict setObject:impressionData.placementType forKey:@"placementType"];
[impressionDataDict setObject:impressionData.renderingSDK forKey:@"renderingSDK"];
[impressionDataDict setObject:impressionData.renderingSDKVersion forKey:@"renderingSDKVersion"];
[impressionDataDict setObject:impressionData.netPayout forKey:@"netPayout"];
[GameAnalytics addImpressionFyberEventWithAdNetworkVersion:[FairBid version] impressionData:impressionDataDict];
}
- (void)interstitialDidShow:(NSString *)placementId impressionData:(FYBImpressionData *)impressionData {
// Use same code as in 'bannerDidShow'
}
- (void)rewardedDidShow:(NSString *)placementId impressionData:(FYBImpressionData *)impressionData {
// Use same code as in 'bannerDidShow'
}
IronSource
To use impression data from IronSource add the following code inside the impressionDataDidSucceed:
// Set delegate
[IronSource setImpressionDataDelegate:delegate];
// Delegate function
- (void)impressionDataDidSucceed:(ISImpressionData *)impressionData {
NSDictionary *all_data = impressionData.all_data;
[GameAnalytics addImpressionIronSourceEventWithAdNetworkVersion:MEDIATION_SDK_VERSION impressionData:all_data];
}
TopOn
To use impression data from TopOn add the following code inside the interstitialDidShowForPlacementID (interstitial given as example the show function other ad types):
-(void) interstitialDidShowForPlacementID:(NSString *)placementID extra:(NSDictionary *)extra {
NSString* version = [[ATAPI sharedInstance].version stringByReplacingOccurrencesOfString:@"UA_" withString:@""];
[GameAnalytics addImpressionTopOnEventWithAdNetworkVersion:version impressionData:extra];
}
MAX
To use impression data from MAX add the following code inside the didDisplayAd (interstitial given as example the show function other ad types):
- (void)didDisplayAd:(MAAd *)ad
{
NSDictionary *impressionDataDict = [NSMutableDictionary dictionaryWithDictionary:@{}];
[impressionDataDict setObject:[ALSdk shared].configuration.countryCode forKey:@"country"];
[impressionDataDict setObject:ad.adUnitIdentifier forKey:@"adunit_id"];
NSString* format = @"";
NSString* d = ad.format.description;
if([d containsString:@"BANNER"])
{
format = @"BANNER";
}
else if([d containsString:@"MREC"])
{
format = @"MREC";
}
else if([d containsString:@"LEADER"])
{
format = @"LEADER";
}
else if([d containsString:@"REWARDED_INTER"])
{
format = @"REWARDED_INTER";
}
else if([d containsString:@"INTER"])
{
format = @"INTER";
}
else if([d containsString:@"REWARDED"])
{
format = @"REWARDED";
}
else if([d containsString:@"NATIVE"])
{
format = @"NATIVE";
}
else if([d containsString:@"XPROMO"])
{
format = @"XPROMO";
}
[impressionDataDict setObject:format forKey:@"adunit_format"];
[impressionDataDict setObject:ad.placement forKey:@"placement"];
[impressionDataDict setObject:ad.creativeIdentifier forKey:@"creative_id"];
[impressionDataDict setObject:ad.revenue forKey:@"revenue"];
[GameAnalytics addImpressionMaxEventWithAdNetworkVersion:[ALSdk shared].version impressionData:impressionDataDict];
}
Aequus
To use impression data from Aequus add the following code inside the adDidShowWithImpressionData:
- (void)adDidShowWithImpressionData:(id<AQImpressionDataProtocol> _Nonnull)impressionData {
NSError* jsonError;
NSData* objectData = [impressionData.jsonRepresentation dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:objectData options:NSJSONReadingMutableContainers error:&jsonError];
[GameAnalytics addImpressionAequusEventWithAdNetworkVersion:json["aequusSdkVersion"] impressionData:json];
}
AdMob
To use impression data from AdMob add the following code inside the paidEventHandler method:
interstitialAd.paidEventHandler = ^void(GADAdValue *value) {
GADInterstitialAd *strongInterstitialAd = weakInterstitialAd;
NSMutableDictionary *impressionDataDict = [NSMutableDictionary dictionaryWithDictionary:@{}];
[impressionDataDict setObject:strongInterstitialAd.adUnitID forKey:@"adunit_id"];
[impressionDataDict setObject:value.currencyCode forKey:@"currency"];
[impressionDataDict setObject:@(value.precision) forKey:@"precision"];
[impressionDataDict setObject:[GameAnalytics adTypeToString:GAAdTypeInterstitial] forKey:@"adunit_format"];
[impressionDataDict setObject:strongInterstitialAd.responseInfo.adNetworkClassName forKey:@"network_class_name"];
[impressionDataDict setObject:value.value forKey:@"revenue"];
[GameAnalytics addImpressionAdMobEventWithAdNetworkVersion:[[GADMobileAds sharedInstance] sdkVersion] impressionData:impressionDataDict];
};
Custom Event Fields
It is possible to use a set of key-value pairs to add extra fields but it will only be available through raw data export. Here is an example of how to use it:
- Swift
- Objective-C
let fields = [String:Any];
fields["test"] = 100;
fields["test_2"] = "hello_world";
GameAnalytics.addImpressionEventWithAdNetworkName(adNetworkName, adNetworkVersion, impressionData, fields];
NSMutableDictionary *fields = [[NSMutableDictionary alloc] init];
fields[@"test"] = @100;
fields[@"test_2"] = @"hello_world";
[GameAnalytics addImpressionEventWithAdNetworkName:[adNetworkName] adNetworkVersion:[adNetworkVersion] impressionData:[impressionData] customFields:fields];
For more information on custom event fields and raw data export go here.
Field | Type | Description | Example |
---|---|---|---|
adNetworkName | string | Name of the ad network related to the impression data. | mopub fyber |
adNetworkVersion | string | Version of the ad network related to the impression data. | 1.0.0 |
impressionData | NSDictionary | The impression data received from the ad network. | adunit_id, currency, precision, adunit_format, network_class_name, revenue |
For more information on Impression Events go here.
Resource Events
Resource events are used to register the flow of your in-game economy (virtual currencies) – the sink (subtract) and the source (add) for each virtual currency.
Before calling the resource event it is needed to specify what discrete values can be used for currencies and item types in the Configuration phase. source (add)
Add gem currency from an in-app purchase.
- Swift
- Objective-C
// Swift
GameAnalytics.addResourceEvent(with: GAResourceFlowTypeSource currency:"Gems" amount:400 itemType:"IAP" itemId:"Coins400")
sink (subtract)
//Objective-C
[GameAnalytics addResourceEventWithFlowType:GAResourceFlowTypeSource currency:@"Gems" amount:@400 itemType:@"IAP" itemId:@"Coins400"];
Subtract gem currency to buy an item.
- Swift
- Objective-C
// Swift
GameAnalytics.addResourceEvent(with: GAResourceFlowTypeSink currency:"Gems" amount:400 itemType:"Weapons" itemId:"SwordOfFire")
GameAnalytics.addResourceEvent(with: GAResourceFlowTypeSink currency:"Gems" amount:100 itemType:"Boosters" itemId:"BeamBooster5Pack")
GameAnalytics.addResourceEvent(with: GAResourceFlowTypeSource currency:"BeamBooster" amount:5 itemType:"Gems" itemId:"BeamBooster5Pack")
// Objective-C
[GameAnalytics addResourceEventWithFlowType:GAResourceFlowTypeSink currency:@"Gems" amount:@400 itemType:@"Weapons" itemId:@"SwordOfFire"];
[GameAnalytics addResourceEventWithFlowType:GAResourceFlowTypeSink currency:@"Gems" amount:@100 itemType:@"Boosters" itemId:@"BeamBooster5Pack"];
[GameAnalytics addResourceEventWithFlowType:GAResourceFlowTypeSource currency:@"BeamBooster" amount:@5 itemType:@"Gems" itemId:@"BeamBooster5Pack"];
Custom Resource Event Fields
It is possible to use a set of key-value pairs to add extra fields but it will only be available through raw data export. Here is an example of how to use it:
NSMutableDictionary *fields = [[NSMutableDictionary alloc] init];
fields[@"test"] = @100;
fields[@"test_2"] = @"hello_world";
[GameAnalytics addResourceEventWithFlowType:GAResourceFlowTypeSink currency:@"BeamBooster" amount:@3 itemType:@"Gameplay" itemId:@"BeamBooster5Pack" customFields:fields];
For more information on custom event fields and raw data export go here.
Field | Type | Description | Example |
---|---|---|---|
flowType | enum | A defined enum for sourcing and sinking resources. | GAResourceFlowTypeSink |
currency | string | The resource type/currency to track. Has to be one of the configured available resource currencies. This string can only contain [A-Za-z] characters. | Gems, BeamBoosters, Coins |
amount | float | Amount sourced or sinked. 0 or negative numbers are not allowed. | 100.0 |
itemType | string | For sink events it can describe an item category you are buying (Weapons) or a place (Gameplay) the currency was consumed. For source events it can describe how the currency was gained. For example “IAP” (for in-app purchase) or from using another currency (Gems). Has to be one of the configured available itemTypes. | Weapons, IAP, Gameplay, Boosters |
itemId | string | For sink events it can describe the specific item (SwordOfFire) gained. If consumed during Gameplay you can simply use “Consumed”. For source events it describes how the player got the added currency. This could be buying a pack (BoosterPack5) or earned through Gameplay when completing a level (LevelEnd). | BoosterPack5, SwordOfFire, LevelEnd, Coins400 |
Be careful to not call the resource event too often! In a game where the user collect coins fairly fast you should not call a Source event on each pickup. Instead you should count the coins and send a single Source event when the user either complete or fail the level.
For more information on Resource Events go here.
Make sure you locally test the instrumented resource events and they are being sent without any difficulties by verifying the info and verbose logs at runtime
Progression Events
Progression events are used to track attempts at completing some part of a game (level, area).
A defined area should follow a 3 tier hierarchy structure (e.g: could be world:stage:level
) to indicate what part of the game the player is trying to complete.
When a player is starting a progression attempt a start event should be added. When the player then finishes the attempt a fail or complete event should be added along with a score if needed.
Add a progression start event.
- Swift
- Objective-C
// Swift
GameAnalytics.addProgressionEvent(with: GAProgressionStatusStart progression01:"world01" progression02:"stage01" progression03:"level01")
// Objective-C
[GameAnalytics addProgressionEventWithProgressionStatus:GAProgressionStatusStart progression01:@"world01" progression02:@"stage01" progression03:@"level01"];
Add a progression start event using only Progression1.
- Swift
- Objective-C
// Swift
GameAnalytics.addProgressionEvent(with: GAProgressionStatusStart progression01:"world01" progression02:nil progression03:nil)
// Objective-C
[GameAnalytics addProgressionEventWithProgressionStatus:GAProgressionStatusStart progression01:@"world01" progression02:nil progression03:nil];
Add a progression complete event with or without score.
- Swift
- Objective-C
// Swift
GameAnalytics.addProgressionEvent(with: GAProgressionStatusComplete progression01:"world01" progression02:"stage01" progression03:"level01" score:15000)
// Objective-C
[GameAnalytics addProgressionEventWithProgressionStatus:GAProgressionStatusComplete progression01:@"world01" progression02:@"stage01" progression03:@"level01" score:15000];
It is not required to use all 3 if your game does not have them, you can have any of the following combinations:
progression01
progression01
andprogression02
progression01
andprogression02
andprogression03
At least progression01
must be set for such events (an empty value is not allowed).
Progressions need to be set in order (e.g: you cannot have only progression01
and progression03
, nor progression02
and progression03
, you are required to start from 01 and continue)
Custom Event Fields
It is possible to use a set of key-value pairs to add extra fields but it will only be available through raw data export. Here is an example of how to use it:
NSMutableDictionary *fields = [[NSMutableDictionary alloc] init];
fields[@"test"] = @100;
fields[@"test_2"] = @"hello_world";
[GameAnalytics addProgressionEventWithProgressionStatus:GAProgressionStatusComplete progression01:@"world01" progression02:@"stage01" progression03:@"level01" score:15000 customFields:fields];
For more information on custom event fields and raw data export go here.
For more information on Progression Events go here.
Field | Type | Description | Example |
---|---|---|---|
progressionStatus | enum | Status of added progression | GAProgressionStatusStart GAProgressionStatusFail GAProgressionStatusComplete |
progression01 | string | Required progression location. | World01 |
progression02 | string | Not required. Use if needed. | Stage01 |
progression03 | string | Not required. Use if needed. | Level01 |
score | integer | An optional score when a user completes or fails a progression attempt. | 1023 |
Design Events
Every game is special. Therefore some needed events might not be covered by our other event types. The design event is available for you to add your own eventid hierarchy.
Please note that custom dimensions and progression filters will not be added on design and error events. Therefore you cannot (at the moment) filter by these when viewing design or error metrics.
To add a design event call the following method.
- Swift
- Objective-C
// Swift
GameAnalytics.addDesignEvent(withEventId: "Kill:Sword:Robot")
// Objective-C
[GameAnalytics addDesignEventWithEventId:@"Kill:Sword:Robot"];
It is also possible to add a float value to the event.
- Swift
- Objective-C
// Swift
GameAnalytics.addDesignEvent(withEventId: "BossFights:FireLord:KillTimeUsed" value:234)
// Objective-C
[GameAnalytics addDesignEventWithEventId:@"BossFights:FireLord:KillTimeUsed" value:@234];
For more information on Progression Events go here.
Custom Design Event Fields
It is possible to use a set of key-value pairs to add extra fields but it will only be available through raw data export. Here is an example of how to use it:
NSMutableDictionary *fields = [[NSMutableDictionary alloc] init];
fields[@"test"] = @100;
fields[@"test_2"] = @"hello_world";
[GameAnalytics addDesignEventWithEventId:@"BossFights:FireLord:KillTimeUsed" value:@234 customFields:fields];