Follow

Integrating the Apmetrix WinRT Component

Intro:

The Apmetrix WinRT SDK Component provides support for the Windows Store & Windows Phone Apps (8.1 OS). The SDK Component is written in C# and is entirely Asynchronous. The SDK Component supports WinJS, C# & C++. The SDK Component provides support for WNS Toast Notifications and Deep Linking.

*Requirement: You are required to use Visual Studio 2013 with Update 2 installed.

*Note: If you are wanting to integrate WNS Push Notifications please read the following article after SDK integration is complete. WNS Push Article

Table of Contents

 

1. Integrating the SDK

Open up Visual Studio 2013 and go to Tools ->NuGet Package manager -> Package Manager Console.

tools-package.png

This will open a console, look for the tab Package Manager Console. Then you will want to set Package Source: to be nuget.org. Next set the Default Project to be your project.

packageCon.png

Using the Package Manager Console type in: Install-Package Apmetrix  This will install the latest package file into your project, setting up the appropriate references.

installPack.png

Then you will see the ApmetrixWind_RTC reference in your References dropdown as shown here via the Solution Explorer. 

appReference.PNG

Please note the Language and follow as needed:

WinJS:

You will want to open up your main JavaScript file (the one that initializes your app) and add the following code at the very top of the file.

var Apmetrix = new ApmetrixWind_RTC.Apmetrix();

This creates the Apmetrix variable which is used to interface with the Apmetrix SDK. You will need to create either create a new object in each JavaScript Page or pass this object to your other scripts.

Js_apmetrix.PNG

*NOTE: This is not  initializing the SDK you will need to call the init function which is discussed below.

C#:

At the top of your c# file beneath your other using statments you will want to add:

using ApmetrixWind_RTC;

cSharp_Apmetrix.PNG

 

C++:

 At the top of your .cpp file beneath your other using statments you will want to add:

using namespace ApmetrixWind_RTC;

c___apmetrix.PNG

Setting up App Capabilities

If you are wanting to take advantage of Apmetrix's GPS location tracking feature you must enable it in your App's Package.appxmanifest file. The ApmetrixWind_RTC SDK does not automatically lookup GPS location. To do so, double-click on the Package.appxmanifest file and it will open up a new tab as shown in the picture below.

appPackageMani.png

Then you will want to click on the Capabilities Tab  

appCap.PNG

and on the Left hand side you will see a list of check boxes. Select Location and then press ctrl+s to save. When you re-launch your app a window will come across the screen asking the user if the app can use their Location. The user can deny this and any attempt to go around this voids your app with the Windows App Store.

LocCap.PNG

 

2. Understanding the Apmetrix Interface Functions

**Note: Each API function returns a value denoting its success or error value. These values are explained in the Method Return Section

**Note: The Apmetrix WinRT Component SDK exposes a Static Async Class that you can use to gain access to the API Functions. Please apply Async logic when using the API.

 Initialize Session

Call the following method in to initialize a session using default permissions:

WinJS:

Since the ApmetrixWinRT Component is Async you will need to use (.then) to get the result from the functions as show below with init

*NOTE: This function defining is needed for each Apmetrix API function for WinJS. The subsequent examples for each API call will just show the API Call without the .then()

Apmetrix.init(int dataset, string version, string unifier, int Optional_Permissions).then(
     function (res) {
               document.getElementById('output').innerHTML = res;
     });

Example With Permissions:

Apmetrix.init(123456789, '1.0.0', '123456QWERTY', Apmetrix.Child_Safe()).then(
     function (res) {
               document.getElementById('output').innerHTML = res;
     });

 

Example Without Permissions:

Apmetrix.init(123456789, '1.0.0', '123456QWERTY').then(
     function (res) {
               document.getElementById('output').innerHTML = res;
     });

 

C#:

await Apmetrix.init(int dataset, string version, string unifier, int Optional_Permissions);

Example With Permissions:

Apmetrix.init(123456, "1.0", "Q1W2E3R4T5Y6", Apmetrix::Child_Safe());

 

Example Without Permissions:

await Apmetrix.init(123456, "1.0", "Q1W2E3R4T5Y6");

 

C++: 

Apmetrix::init(int dataset, Platform::String ^version, Platform::String ^unifier, int Optional_Permissions);

Example With Permissions:

Apmetrix::init(123456, L"1.0", L"Q1W2E3R4T5Y6", Apmetrix::Child_Safe());

 Example Without Permissions:

Apmetrix::init(123456, L"1.0", L"Q1W2E3R4T5Y6");

 

Note 1: The appDataset and appUnifier can be found in the dashboard under Your Profile Picture->Administration->Accounts and expanding Datasets, then select your Dataset.

Note 2: If needing to initialize the session with non-default permissions you can select from any combination of the following options. If more than one option is desired the options can be or'd together using the | character:

 Apmetrix.No_Ad_Id()

 The device's unique identifier is NOT sent to the server

 Apmetrix.Use_GEO_Lookup()

 The device will track GPS location. By default the sdk will not track GPS.

 Apmetrix.Child_Safe()

 Combination of the NO_GEO_LOOKUP, and NO_UDID permissions

 Apmetrix.Use_Push()

 Tells the SDK to initialize WNS services

 Apmetrix.Url_Logging()

 Tells the SDK to log all outgoing URLS to the console. Need to use Debug Component Debug-Download

 

Adding Custom Events

Log Event Details (Universal):

table

Predefined value for the type of Apmetrix.CustomEvent

dimensions

Variable length comma delimited list of custom event dimensions.

 

Note: The platform has the ability to take in up to 25 string dimensions (maximum) and 20 metric dimensions (maximum).

Adding custom events to your game or app is hugely beneficial and highly encouraged as it allows you to track many types of events and actions that users and applications generate.  Our platform allows you to pass in an unlimited number of these events and track them in many different ways.  While this functionality is extremely powerful, it can also be very unwieldy if some best practices are not thought of or contemplated in advance.  While you can of course create as many dimensions as you like (up to 24 in fact), we have suggested a logical way using 4 dimensions which may make it easier to create and and report on your custom data.

Integer values for the table parameter are as follows:

(1)       Apmetrix.Un_Grouped_Table()

The dimension data is ungrouped

(2)       Apmetrix.Users_Table()

The dimension data pertains to the user

(3)       Apmetrix.Apps_Table()

The dimension data pertains to the application

As a game or app can have many such custom events, it is important to logically categorize your local application variables as you would logically think such an event should be tracked.  A suggested structure (at least for the first four dimensions) would be as follows;

  • Verb – What event is occurring such as “crashed”, “invited”, “fired”, “damaged” etc.
  • Object – What action is occurring on what object such as “car”, “friend”, “house” etc.
  • Location – Where did such an event occur?  It is useful to think of this within the context of your game or app as each is different based on context.  For example; for an adventure game you may want to list the map or level where the event occurred.  For a racing game, perhaps the track, or for a puzzle game, the name of the puzzle or level.  Think in terms of relevant location data you’d need to know.
  • Value – This is additional information in the form of a string you may wish to pass in depending on the specific event you are tracking. For example; you may want to pass in the time for the car crashed, determine whether a condition was True or False, etc.
  • Numerical Value - This is additional information you may wish to pass in depending on whether or not you need to pass in a number (i.e. if you want to track currency or economy flows such as "Primary Currency at Session Start", Primary Currency Earned", "Primary Currency Spent", "Primary Currency at Session End" ).

Important Notes:

Since the system defaults to treating incoming data as strings, you will need to include the “#” symbol in front of your metric data so the system recognizes it as a numerical value.

Also note that since these are literal examples you will need to replace the parameter with the actual local game variable you wish to pass in to the platform so as to appropriately reflect your own data structure.

Examples:

WinJS:

Apmetrix.logEvent(int table, string[] arrayP);

Defining the Table Types in your JS file:

var ApmetrixUT = Apmetrix.users_Table();
var ApmetrixAT = Apmetrix.apps_Table();
var ApmetrixUGT = Apmetrix.un_Grouped_Table();

Example:

Apmetrix.logEvent(ApmetrixAT, ['Crashed', 'Tank', 'Tundra', 'DMG', '#400' ]);

Verb - Crashed, 

Object - Tank,

Location - Tundra,

Value - DMG,

Metric 1 - Will always be 1 (Signifies the event happened)

Metric 2- 400

Example With Spaces: 

Apmetrix.logEvent(ApmetrixAT, ['Crashed', 'Tank', '', 'DMG', '#400' ]);

Verb - Crashed, 

Object - Tank,

Location - Empty,

Value - DMG,

Metric 1 - Will always be 1 (Signifies the event happened)

Metric 2- 400

C#:

Apmetrix.logEvent(int table, string[] arrayP);

Example:

await Apmetrix.logEvent(Apmetrix.Users_Table(), new string[] { "Crashed", "Tank", "Tundra", "DMG", "#400" });

Verb - Crashed, 

Object - Tank,

Location - Tundra,

Value - DMG,

Metric 1 - Will always be 1 (Signifies the event happened)

Metric 2- 400

Example With Spaces: 

await Apmetrix.logEvent(Apmetrix.Users_Table(), new string[] { "Crashed", "Tank", "", "DMG", "#400" });

Verb - Crashed, 

Object - Tank,

Location - Empty,

Value - DMG,

Metric 1 - Will always be 1 (Signifies the event happened)

Metric 2- 400

C++:

Apmetrix::logEvent(int table, Platform::Arry<Platform::String ^, 1U> ^arrayP);

Example:

Apmetrix::logEvent(Apmetrix::Users_Table(), ref new Platform::Array<String^, 1>{ L"Crashed", L"Tank", L"Battleground", L"DMG", L"#400" });

Verb - Crashed, 

Object - Tank,

Location - Battleground,

Value - DMG,

Metric 1 - Will always be 1 (Signifies the event happened)

Metric 2- 400

Example With Spaces: 

Apmetrix::logEvent(Apmetrix::Users_Table(), ref new Platform::Array<String^, 1>{ L"Crashed", L"Tank", L"", L"DMG", L"#400" });

Verb - Crashed, 

Object - Tank,

Location - Empty,

Value - DMG,

Metric 1 - Will always be 1 (Signifies the event happened)

Metric 2- 400

 

  

ApTrak

Call the following method to track user interaction, logging the coordinates for a specified event at a specified location or screen:

WinJS:

Apmetrix.ApTrak(string event, string loc, string[] coordsP);

C#:

await Apmetrix.ApTrak(string event, string loc, string[] coordsP);

C++:

Apmetrix::ApTrak(Platform::string ^event, Platform::string ^location, Platform::Arry<Platform::String ^, 1U> ^coords);
 

ApTrak EXAMPLE:

Event coordinates should be input in the following order:

X (required), Y (required), Z (optional) and W (optional)

WinJS:

Apmetrix.ApTrak('Clicked', 'Start Level', ['13.5', '12.7']);

C#:

await Apmetrix.ApTrak("Clicked", "Start Level", new string[] { "13.5", "12.7"});

C++:

Apmetrix::ApTrak(L"Clicked", L"Start Level", ref new Platform::Array<String^, 1>{"13.5", "12.7"});

 

In Application Purchases

To log a purchase made with real currency (as opposed to virtual currency):

This function ties to the In-App Purchases Table. 

Function Call - when you want the converted cost to be generated based on:

  • The SDK attempts to get the locale of the App from App Store APIs. If this fails the SDK will default to determining the users country via IP.
  • your country's currency (the country you specified when you created an account with Apmetrix) :

WinJS:

Apmetrix.inApPurchase(int qty, string item, string location, float itemCost, string localCurrency);

C#:

await Apmetrix.inApPurchase(int qty, string item, string location, float itemCost, string localCurrency);

C++:

Apmetrix::inApPurchase(int qty, Platform::String ^item, Platform::String ^location, float itemCost, Platform::String ^localCurrency);

where

 quantity

identifies the amount of items purchased

 item

identifies the item(s) that were purchased

 location

identifies where within the application the user purchased the items

 itemCost

identifies the cost that the user purchased the item(s) for

 localCurrency

currency that the user purchased the items with.  Pass in 0 if you do not know the local currency and want the SDK to look it up.

In Application Purchase Code Examples:

Following are some examples that demonstrate use of the inApPurchase() function using both function call options.

If you do not know the local currency or what currency you want to convert to use this example. We will do the conversion server side using data from your App Setup on the Apmetrix Dashboard.

WinJS:

Apmetrix.inApPurchase(1, 'Truck of Coins', 'Marketplace', 5.99, '0');

C#:

await Apmetrix.inApPurchase(1, "Truck of Coins", "Marketplace", 5.99, "0");

C++:

Apmetrix::inApPurchase(1, L"Truck of Coins", L"Marketplace", 5.99, L"0");

 

Virtual Item Transaction Tracking

Call the following method  to log virtual item transactions.

WinJS:

Apmetrix.virtualItem(string trans, int qty, string item, string location, int[] currenP);

C#:

await Apmetrix.virtualItem(string trans, int qty, string item, string location, int[] currenP); 

C++:

Apmetrix::virtualItem(Platform::String ^trans, int qty, Platform::String ^item, Platform::String ^location, Platform::Array<int, 1> ^currenP);

 

where

 transaction

identifies the transaction that was made ("Bought", "Sold", "Traded", etc.)

 quantity

identifies the amount of items involved in the transaction

 type

identifies the type of item(s) involved in the transaction

 location

identifies where within the application the transaction took place

 currencyAmounts

a list of currency amounts for the item(s).  Up to 3 different denominations can be specified but denominations must be kept in the same order each time this function is called.

 Use this function when you want to track the flow of in-game items & in-game currency. This function ties to two tables (Virtual Currency & Virtual Items) on the Apmetrix Dashboard. 

Examples:

This example shows 1 Wand of Hate was sold at the Evil Shop for 15 primaryCurrency, 20 secondaryCurrency and 5 tertiaryCurrency

*Note: A minus (-) next to the number denotes that the currency was spent. Where as no minus (-) denotes the currency was earned

WinJS:

Apmetrix.virtualItem('Bought', 1, 'Wand of Hate', ' Evil Shop', [-15, -20, -5]);

C#:

await Apmetrix.virtualItem("Bought", 1, "Wand of Hate", "Evil Shop", new int[] { -15, -20, -5});

C++:

Apmetrix::virtualItem(L"Bought", 1, L"Wand of Hate", L"Evil Shop",  ref new Platform::Array < int, 1 > { -15, -20, -5 });

 

This example shows 1 Wand of Luck was sold at the Evil Shop for 15 primaryCurrency, 20 secondaryCurrency

WinJS:

Apmetrix.virtualItem('Sold', 1, 'Wand of Luck', 'Evil Shop', [15, 20]);

C#:

await Apmetrix.virtualItem("Sold", 1, "Wand of Luck", "Evil Shop", new int[] {15, 20});

C++:

Apmetrix::virtualItem(L"Sold", 1, L"Wand of Hate", L"Evil Shop", ref new Platform::Array < int, 1 > { 15, 20 });

 

Virtual Currency Tacking 

Use this function to track the flow of virtual in-game currency.  To log a virtual currency transaction call:

WinJS:

Apmetrix.virtualCurrency(string trans,  string location, int[] currenP);

C#:

await Apmetrix.virtualCurrency(string trans, string location, int[] currenP); 

C++:

Apmetrix::virtualCurrency(Platform::String ^trans, Platform::String ^location, Platform::Array<int, 1> ^currenP);

 

where

 transaction

identifies the transaction that was made ("Bought", "Sold", "Traded", etc.)

 location

identifies where within the application the transaction took place

 currencyAmounts

a list of currency amounts for the item(s).  Up to 3 different denominations can be specified but denominations must be kept in the same order each time this function is called. 

Virtual Currency Transaction Code Examples:

The following is an example that demonstrates use of the virtualCurrency() function when 12 units of a primary currency, 0 units of secondary currency and 24 units of a tertiary currency were earned:

WinJS:

Apmetrix.virtualCurrency('Looted', 'Forest', [12, 0, 24]);

C#:

await Apmetrix.virtualCurrency("Looted", "Forest", new int[] {12, 0, 24});

C++:

Apmetrix::virtualCurrency("Looted", "Forest",  ref new Platform::Array < int, 1 > {12, 0, 24 });

 

The following is an example that demonstrates use of the virtualCurrency() function when 24 units of a primary currency and 12 units of a secondary currency were spent:

WinJS:

Apmetrix.virtualCurrency('Looted', 'Forest', [-24, -12]);

C#:

await Apmetrix.virtualCurrency("Looted", "Forest", new int[] {-24, -12});

C++:

Apmetrix::virtualCurrency("Looted", "Forest",  ref new Platform::Array < int, 1 > {-24, -12});

 

Offer Tracking

Call the following method  to log offers that are presented/accepted/declined.

WinJS:

Apmetrix.offer(int type, string offerType, string location); 

C#:

await Apmetrix.offer(int type, string offerType, string location); 

C++:

Apmetrix::offer(int type, Platform::String ^offerType, Platform::String ^location); 

where

 transaction

identifies the transaction that was made and has the following meanings:

 Apmetrix.Presented() - used to denote an offer presented to the user

 Apmetrix.Accepted() - used to denote an offer accepted by the user

 Apmetrix.Declined() - used to denote an offer declined by the user

 offer

identifying the actual offer "30% off weekend sale", "10% off all Gems", etc

 location

identifies where within the application the offer was presented, accepted or declined. "Main Menu", "Pay To Rush", "Cash Shop", etc

This function ties to the Offers Table on the Apmetrix Dashboard.

Examples:

WinJS Values: 

var ApmetrixAc = Apmetrix.accepted();
var ApmetrixPres = Apmetrix.presented();
var ApmetrixDec = Apmetrix.declined();

Use this example when you want to track an offer that was Presented to the user

WinJS:

Apmetrix.offer(ApmetrixPres, '20% Off All Packs', 'Main Menu'); 

C#:

await Apmetrix.offer(Apmetrix.Presented(), "20% Off All Packs", "Main Menu"); 

C++:

Apmetrix::offer(Apmetrix::Presented(), L"20% off Stuff", L"Marketplace");

 

Use this example when you want to track an offer that was Accepted by the user

WinJS:

Apmetrix.offer(ApmetrixAc, '20% Off All Packs', 'Main Menu'); 

C#:

await Apmetrix.offer(Apmetrix.Accepted(), "20% Off All Packs", "Main Menu"); 

C++:

Apmetrix::offer(Apmetrix::Accepted(), L"20% off Stuff", L"Marketplace");

Use this example when you want to track an offer that was Declined by the user

WinJS:

Apmetrix.offer(ApmetrixDec, '20% Off All Packs', 'Main Menu'); 

C#:

await Apmetrix.offer(Apmetrix.Declined(), "20% Off All Packs", "Main Menu"); 

C++:

Apmetrix::offer(Apmetrix::Declined(), L"20% Off All Packs", L"Main Menu");  

 

Start Timer

Call the following method to start a new timer:

WinJS:

Apmetrix.startTimer(string name); 

C#:

await Apmetrix.startTimer(string name); 

C++:

Apmetrix::startTimer(Platform::String ^name);

Where timerName is the name of the timer. If you start a timer and that timer already exists then the system will override the existing timer.

Example:

WinJS:

Apmetrix.startTimer('Test Timer'); 

C#:

await Apmetrix.startTimer("Test Timer"); 

C++:

Apmetrix::startTimer(L"Test Timer");

 

Stop Timer

Call the following method to stop an existing timer:

WinJS:

Apmetrix.stopTimer(string Name);  

C#:

await Apmetrix.stopTimer(string Name);

C++:

Apmetrix::stopTimer(Platform::String ^Name);  

Where timerName is the name of the existing timer. The system will only stop timers that exist.

Example:

WinJS:

Apmetrix.stopTimer('Test Timer'); 

C#:

await Apmetrix.stopTimer("Test Timer"); 

C++:

Apmetrix::stopTimer(L"Test Timer"); 

 To better understand Timers it is recommended that you view the article on timers found here.

 

Pause Timers

Call the following method to pause all active timers.

WinJS:

Apmetrix.appDidEnterBackground();

C#:

await Apmetrix.appDidEnterBackground(); 

C++:

Apmetrix::appDidEnterBackground();

 To better understand Timers it is recommended that you view the article on timers found here.

 

Resume Timers 

Call the following method to resume all active timers.

WinJS:

Apmetrix.appWillEnterForeground(); 

C#:

await Apmetrix.appWillEnterForeground(); 

C++:

Apmetrix::appWillEnterForeground(); 

 To better understand Timers it is recommended that you view the article on timers found here.

 

Start Level

Call this function when a player starts a new level. This is used to record how long it took the player to reach the each next level.

WinJS:

Apmetrix.startLevel(string levelName);

C#:

await Apmetrix.startLevel(string levelName); 

C++:

Apmetrix::startLevel(Platform::String ^levelName);

 

Example:

Called when the player starts level 1. You will need to add logic that only triggers this function once, if you were to trigger the function each time the user starts level 1 it will reset the timer.

WinJS:

Apmetrix.startLevel('Level 1'); 

C#:

await Apmetrix.startLevel("Level 1"); 

C++:

Apmetrix::startLevel(L"Level 1");  

 

Called when the player levels up or starts a new level.

WinJS:

Apmetrix.startLevel('Level 2'); 

C#:

await Apmetrix.startLevel("Level 2"); 

C++:

Apmetrix::startLevel(L"Level 2");  

 

CUSTOMER TRACKING

 - Use this function to track a customer ID so it can be correlated with the rest of the data being tracked on this mobile device for this user.  This method is useful for applications where the user can be identified via a logon ID or user id, thus allowing the rest of the data tracked to be correlated on a per user basis.  To log a customer ID call:

WinJS:

Apmetrix.setCustomerId(string customerId);

C#:

Apmetrix.setCustomerId(string customerId);

C++:

Apmetrix::setCustomerId(Platform::String ^customerId);

where

 customerId

 identifies the user playing the game or logged on to the app.

Customer Tracking Code Example:

The following is an example that demonstrates use of the setCustomerId() function where "123456789-98764321" is the ID the customer is identified by:

Typically you will want to call this before init so putting it in your Init function works great.

WinJS:

Apmetrix.setCustomerId('1234-567-890');

C#:     

Apmetrix.setCustomerId("1234-567-890");

C++:

Apmetrix::setCustomerId(L"1234-567-890");

 

Set Upload Interval

Call this function to indicate how many minutes the SDK should wait before sending data to the Apmetrix Server.

Typically you will want to call this before init so putting it in your Init function works great.

WinJS:

Apmetrix.setUploadInterval(int minutes);

C#:

Apmetrix.setUploadInterval(int minutes);

C++:

Apmetrix::setUploadInterval(int minutes);

 

Example:

This example tells the SDK to wait 5 minutes before sending data.

WinJS:

Apmetrix.setUploadInterval(5);

C#:

Apmetrix.setUploadInterval(5);

C++:

Apmetrix::setUploadInterval(5);

 

Set Aptrak Bundle Count

Call this function to indicate how many ApTrak calls you want to bundle before sending them to the Apmetrix Server. If you set the count to 1 then there will be no bundling.

Typically you will want to call this before init so putting it in your Init function works great.

WinJS:

Apmetrix.setBundleCount(int size);

C#:

Apmetrix.setBundleCount(int size);

C++:

Apmetrix::setBundleCount(int size);

 

Example:

This example bundles 50 ApTrak calls together then sends the data to the Apmetrix server

WinJS:

Apmetrix.setBundleCount(50);

 

C#:

Apmetrix.setBundleCount(50);

 

C++:

Apmetrix::setBundleCount(50);

 

Restart Session

Call the following method to restart a session that had previously been initialized but closed:

WinJS:

Apmetrix.restartSession();

C#:

await Apmetrix.restartSession(); 

C++:

Apmetrix::restartSession(); 

 

End Session 

Call the following method to close a session that is open:

WinJS:

Apmetrix.endSession(); 

C#:

await Apmetrix.endSession(); 

C++:

Apmetrix::endSession(); 

Method Return Values

All methods will return the following based on validation from the server: 

Return Val.  Reason Why
 0  Sdk event was successfully sent to server
 101  Init already called, session open thus ignored
 103  Event was called with no active session, call ignored
 201  Invalid Dataset/Unifier or function params were passed in

 

Have more questions? Submit a request