Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Once you've created the space, you'll see the Add Application button in the devtodev interface. Click on it to add an application to the space.
First, you need to select a platform.
The next step is optional. You can test the integration in test mode. It assumes that up to 100 different users can use the app, and their data will be excluded from statistics.
When you switch test mode off, all the users who sent the data will be marked as testers in your real account.
During the next step, you can add an account to collect data from the market or skip this step and add this information later.
The final step is to fill in the name of your app and select its genre and type. Select app type: game or app. If you choose “app” as the type, gaming events will not be tracked and displayed in the interface, even if they are integrated. Also, game-related elements will be hidden in the interface.
Please note that you can select more than one genre.
Congratulations, you have added the application to the space!
Now you can see the standard devtodev interface and all the reports. Of course, the reports are empty until you start sending data to devtodev.
If you have added an account to collect data from the market, it will take 1 day to build the report.
If your integration uses SDK (in most cases), the next step is to integrate SDK into your app. Please read our expert tips on integration, select the necessary SDK, integrate it, and start using devtodev's full functionality!
And please don't hesitate to ask us questions. You can find the 'Support' button on the top right of the devtodev interface.
You can change the project type at any time in the Settings → section.
devtodev documentation helps you to gain in-depth knowledge of the product and use all opportunities offered by the platform.
Thanks for choosing devtodev analytics!
devtodev provides SDKs that give you the ability to measure users’ behavior and player journeys using basic and custom events. We have SDKs for the most popular OS and engines:
We have SDKs for the most popular OS and engines:
Here are some simple steps to start using our service:
Here are some of the new features you might have missed.
Released: 21/06/2024
You can now save Conversion to N payment, Period until payments, Top converting goods charts to a custom dashboard as widgets. This information will help you analyse the payments in a more convenient way.
Released: 21/06/2024
The Like opertor allows you to create a mask for the string parameter values.
For example, you have a parameter called Item and it has values: offer1, offer2, offer3, offer4. Use the Like operator and type offer, this will select all four of these values in the resulting report.
Released: 21/06/2024
The Locations report contains ready-made metrics that allow you to see how users pass the different locations. You can now save this report to a dashboard with other metrics to see the whole picture.
Released: 14/05/2024
This update gives you an ability to change the name of any metric in Custom events. You can use more convenient titles and adjust the values with a Round setting. There is also an option to change the Units for a single number widget. The applied metrics' settings will also be saved when you share the report or add it to a dashboard.
Released: 14/05/2024
Results from Devtodev’s Cumulative ARPU report can now be saved to a custom dashboard as a widget. This information helps you track crucial Cumulative ARPU metric values for your project.
Released: 30/04/2024
Previously data from Custom Postback API or SDK Install referrer was not available in the Acquisition section. Now, we have added a Source filter in the Detailed stats report, where you can select the needed trafic sources.
Released: 30/04/2024
Released: 10/04/2024
With this update, we have extended the expiration date for unused segments to 60 days. If you do not apply the segment to any report, it will expire. However, you will have 30 days to recover this segment before it’s completely deleted.
Released: 21/03/2024
Users now are able to customize axis boundaries on their charts to more accurately represent data trends. In cases where the charts are not optimally positioned (or you are not happy with their placement, or want to change the position of the chart), simply clicking on the Axis Scale option allows you to define the minimum and maximum values for the axis.
Released: 20/03/2024
When a user deletes their account, or in case the user is removed from the space, their content remains in devtodev. Now, the team can manage the ownership of such content. For example, you can take ownership of the report made by the deleted user, or you can delete it from the space.
Released: 20/03/2024
When the space owner is changing, they need to transfer their ownership. With this update, the owner of the space can select a new owner in User settings and delegate their owner access.
Released: 12/03/2024
We’ve added a new metric to our Basic Metrics report – the Cohort Timespent. Previously, you may have known this metric as “Cohort Playtime,” which was created specifically to evaluate user engagement in the Sessions report. And now this metric is also available in Basic Metrics for both game projects and applications.
Released: 27/02/2024
Now you can create games and apps from scratch on all popular engines, including Godot, all while utilizing detailed data analytics tools. Devtodev platform will support you in understanding player behavior, optimization, and increasing user engagement throughout the entire lifetime of the product.
The new Godot SDK is now available for iOS, macOS, and Android platforms, providing you with the tools you need to take your games and apps to the next level.
Learn how to integrate Godot SDK:
Released: 28/01/2024
An existing dynamic segment can be duplicated with just one click. Simply copy the segment and adjust its settings to save time when creating a segment with similar conditions.
Released: 09/01/2024
You can receive notifications if the number of basic or custom events suddenly changes or differs from a specific day. These alerts will inform you about any positive or negative fluctuations.
Also, two new conditions have become available: a comparison with the previous day and a comparison with the same day last week. This allows the alert to activate when yesterday's event count is different from the count on the chosen day.
Space is an information field where you will work. Later on, you will add your application to the space.
Click on the Create space button in the devtodev interface.
To create a space, you need to fill in:
Name
Time zone
Logo (optional)
The time zone is important because it defines the time when one day ends and another one begins.
We offer a 30-day free trial for all new users (only for the first space created using this email). Note that the trial period begins at the moment you create a Space.
That's it! You've created your space, and now you can add apps to it.
Here are some of the new features you might have missed.
Released: 20/12/2023
Results from Devtodev’s Retention report can now be added to a custom dashboard as a widget. This information helps you track crucial retention metric values for your project. The update eliminates the need for SQL in building the report and adding it to the dashboard.
Here are some examples of how you can use this functionality:
Add a widget with data on the retention of users who signed up for a specific subscription plan.
Display the retention of users who signed up for your project and then performed a desired action (e.g., created a project, started a workout, or invited a friend).
Compare the retention of users who engaged with your new features with those who did not (e.g., completed/skipped onboarding).
Add several widgets to compare the retention of users who used different methods of doing something (e.g., project creation, battle modes, price plans, payment methods, etc.).
Released: 05/12/2023
Devtodev’s Custom event, Custom funnels, and User flow reports got a new operator and parameter value that will increase their flexibility. Use the 'IS NOT' operator and 'null' parameter value to exclude certain parameters and to work with events that do not return any value.
Released: 21/11/2023
You can disable any property that you have previously added and now consider unnecessary or faulty. For example, if you initially collected the 'user type' property (such as beginner or pro), but have since decided to focus on the 'user status' property (guest/registered), you can disable the 'user type' property to maintain a cleaner and more organized report-building process.
Released: 20/11/2023
With this update a familiar 1x1 widget from SQL and Basic Metrics becomes available in the Custom events report. Select Report type -> Number and a single number for your most important KPI is ready for your dashboard.
Here are some examples of what you can check: number of in-app shop openings, average battle time in a game, conversion from workout start to finish.
Released: 30/10/2023
When creating a new devtodev project, you can now select the type of project: a game or an application. This choice will affect the customization of the devtodev interface. Depending on the type, specialized reports will be available.
You can always change the type of the project later in Settings -> General settings.
Released: 19/09/2023
Devtodev users are familiar with the 1x1 widget — a small module on your dashboard containing a single number designed to keep you informed about important metrics. With the latest update from Devtodev, you no longer need to use SQL to create widgets with basic metrics. You can simply open the Basic Metrics report, select a metric, click View -> Number, and then add this number as a widget to your dashboard. This will not only save you valuable time but also enable you to use a limited number of SQL widgets to display other metrics.
Released: 29/08/2023
When it comes to data visualization, Devtodev offers plenty of powerful tools, and SQL widgets is one of them. To give you access to even more data points on your dashboards, we’ve introduced an update that offers you the ability to display two metrics on a single 1x1 widget. Simply write a single query and get two numbers: it is easy, convenient and requires less time than creating separate queries for two individual widgets.
Released: 16/08/2023
Devtodev’s clients frequently create funnels to analyze various aspects of their apps and games. However, these funnels are often longer than a single screen, and the users find themselves having to scroll excessively, which can be quite inconvenient.
Released: 25/07/2023
The overview provides essential metrics for all projects in Space, allowing users to conventionally track the metrics of the projects. Additionally, it offers the option to access the prepared reports in the selected project to analyze metric rises or falls. The overview aims to briefly introduce each project's key metrics and keep users informed about devtodev's news.
Released: 18/07/2023
By tapping on the step in the report, you can assign a name that describes the action and facilitate seamless collaboration among all team members working on the app.
Released: 27/06/2023
In our latest update we added distribution by parameter (Show % of total) across all the Basic metrics report tables. This feature proves particularly valuable when you need to determine the percentage of users with a specific attribute in relation to the total number of users in a particular group. It’s extremely convenient because you don’t need to waste time on creating separate SQL queries anymore!
Released: 20/06/2023
With this update, we’ve introduced two additional options for two calculation methods (by calendar days and by 24-hour interval):
Flexible calculation start: you can now choose a specific event or several events that define a cohort for retention calculation, allowing for more tailored analysis..
Custom calculation end: you have the freedom to select a particular event that signifies a user’s return to the product, enabling more precise measurement.
Released: 25/05/2023
This update got you two new features in the Funnel report (Reports -> Conversion funnel): an alternative event that you can use when building a funnel, and an option for creating a segment of users who failed to complete all the funnel steps.
Released: 02/05/2023
What we did:
Added display of item groups. The groups may come in handy in case you have too many items.
Added breakdown by levels.
Introduced a number of purchases divided by the DAU metric value (“% of active”, as in the Custom events report).
Improved mean value. After the update, we calculate it as the number of items purchased at a level divided by the number of users.
Released: 17/04/2023
You can now activate Data labels on charts in Basic Metrics, Custom events or SQL reports. Use them to evaluate the dynamics and values in one glimpse.
Released: 04/04/2023
Sharing dashboards has never been so easy and convenient! devtodev already has a wide range of tools that make your work more smooth and unhindered, however, the export to pdf tool takes the process to the next level.
It’s an extremely convenient option for both senders and recipients. The senders can make sure that the recipients get only the data that they want to share with them in the exact form that they intended to show them. The recipients can get access to data without going through the whole process of signing up to the devtodev platform.
Released: 07/03/2023
If you are curious about the number of users who achieve the ultimate goal during the first or the Nth session (first two, three, etc.), you can easily calculate them, build a segment and then analyze thoroughly. Simply click on ‘Conversion time limit’, set a sequential number of the session and build a funnel.
Now you can also rename funnel steps!
Released: 16/02/2023
If you have a child-directed app or game, you may worry that the data you send to devtodev is anonymised and protected enough. It’s not a problem anymore with our updated SDK because it operates in full compliance with COPPA — the Children's Online Privacy Protection Act.
This updated version of devtodev SDK does not collect, process or store ad IDs of children. It simply creates anonymised user identification numbers that can be used by the platform for tracking underaged users without influencing the decisions they make.
If you already use devtodev SDK, all you need to do is to enable the COPPA-compliance opinion before SDK initialization and delete the dependencies necessary for processing ad and vendor IDs. This will not interfere with your working process because almost all devtodev reports will stay available and you will be able to use them as you did before.
Released: 14/02/2023
We’ve added 1, 7, 14 and 30-day Cumulative ARPU to the A/B tests. You can use these metrics to improve the quality of the analysis and prove that the implemented changes did not influence other key metrics of the app.
Released: 17/01/2023
Drill down into your user flow data by setting a limit on the number of user sessions! This option comes in handy in case you want to take a closer look at what your users managed to achieve during, let’s say, their first session, and compare it with your expectations.
There are three options in this report - “No”, “Limit by first session”, and “Limit by number of sessions”. If you want to see events that users completed during their first session, choose the second option. If you want to see data for several sessions, choose the third option. In this case, the calculation is as follows: we take the specified number of sessions performed during the selected period, then we take the dates of the first and the last sessions, and after that we analyze the events performed during this period.
To begin working with analytics, you need to start sending events (information about user activity in the project) to the analytics system.
devtodev provides basic events that drive the majority of the reports.
Users start with opening the app, and this process we call "starting a session". For your convenience, in the majority of devtodev SDKs this event is integrated automatically.
There is no separate event in devtodev that describes a session by its duration and start or end date.
We use two events that we can use to examine the duration of the sessions. The first event captures the start date of a new session and the second captures the duration of each application activity (time when application is in focus). In our experience, this is the most reliable solution at the moment.
At the moment when application receives focus (this may be the moment the SDK is initialized / the application is opened / the device wakes up from the sleep mode with the focus on the application), we begin to assume that the application becomes active and begin to count the duration of the activity.
If the application loses focus (minimizing the application / device is going into the sleep mode / switching to another application / exiting the application), we consider that the activity is completed and we send its duration to the devtodev server. This is an application activity event.
If users can use real money to make purchases in your project, you need to integrate the Payment event. When devtodev receives data about sessions and payments in your app, we can calculate all financial metrics (gross, revenue, average check) and metrics of the project’s financial efficiency (ARPU, ARPPU, paying share, LTV).
If your application has subscriptions, you can integrate this event to analyze the financial data as well as the structure of your subscribers. Devtodev integrations allow you to receive information about subscription purchases even if the user doesn’t open the app (auto-renewable subscriptions).
Using this event you can evaluate the effectiveness of the tutorial steps system, analyze how users complete the tutorial, find bottlenecks, and measure the time it takes for users to complete the tutorial. The event should be sent at the end of each tutorial step indicating the number of completed steps as a parameter.
Here are some predefined values for the Tutorial Step event parameter:
0 - the user skipped the tutorial
-1 - the user started the tutorial
-2 - the user finished the tutorial
devtodev is a universal analytics system, and our structure of basic events is designed for game projects specifically. However, there may be situations when your project requires events that are not provided by the devtodev basic events. Such events can still be sent and analyzed in our system - as custom events.
Here are some examples of users' actions that can be sent as custom events: when users open an in-game store, click on items, buy items. Based on these events, you can build a funnel and see the conversion on each step.
Some limits for custom events:
The number of different event types sent from one project shouldn't exceed 300.
The event name must not exceed 72 characters.
One event can contain up to 20 parameters, which must have unique names of up to 32 symbols.
Parameters can be string and numeric: - the maximum length of parameter values is 255 characters; - the number of string parameter values cannot exceed 50 000; when it exceeds 50 000, the further sending of information about the parameter and possibilities to work with it will be blocked.
Here is some expert advice to avoid problems with limits in custom events:
There is no need to send user IDs in parameters (they are collected by default).
Do not send time in the timestamp format (it is also collected by default).
You can analyze the distribution of the players over the levels. Many game projects have levels, which means that as users become more experienced, they gradually increase their level. In this case levels have a linear structure: the level N is followed by the level N+1. If your project has in-game currency, using the LevelUp event you can send information about the current amount of in-game currency players have. This data allows evaluating the average amount of in-game currency that players have on a particular level.
The event should be sent right after the player reaches the next level.
This specific event is a part of the LevelUp event and does not require a separate dispatch. Send this event to track the average amount of in-game currency earned or purchased during a level after each time an in-game account is replenished.
There are many projects (for example, Match-3 games), where players make an attempt to complete a level. Their attempts may be either successful or unsuccessful. In addition, during a certain attempt different numerical indicators can be changed: the number of stars, resources, in-game currency.
To analyze such attempts, devtodev provides a basic Progression event. In the Progression event you send information about how players pass a particular game location, whether their attempt is successful, and how numerical indicators change.
Many games, especially f2p, have in-game currency. Players can spend it on virtual goods. To work with virtual currency purchases, devtodev has developed the Virtual Currency Payment event.
on your dashboard. Improve readability by adjusting the column width automatically (Autofit column width) or by hand. We have also added a Wrap text option for heading and table rows to allow for longer titles.
To alleviate this issue, we have recently introduced the 'Step' option to the report. It is designed to save our clients time and effort while streamlining the funnel exploration process.
This update empowers you to enhance collaboration among team members by giving each step in the report a meaningful and easy-to-understand name of your choice.
devtodev’s has got several new features that will enable you to narrow down the audiences and calculate this metric more effectively.
This time we added several great features to the report’s section. They allow for a much deeper analysis of in-game currency, purchases, and real money spends.
Analyzing using devtodev funnels is as easy as it can be! To make the process more convenient, we are introducing ‘limitation by session’ — a new additional option that will help you with analyzing any particular user session. Now building a funnel is as easy as creating any devtodev out-of-the-box reports — simply click and analyze every aspect of it.
Read more about it in our documentation: , , and
We consider the start of a new session to be the moment when the application receives focus (see the description above), but at the same time we take into account that more than 10 minutes have passed since the last activity of the application. Otherwise, we count that the previously launched session continues. More detailed information on tracking sessions can be found on the '' page.
This event is for games only. It is worthwhile to integrate this event into a game type project, as specified in the . In projects with the “app” type, game events will not be tracked and displayed in the interface, even if they are integrated. You can verify and change the project type in Settings → .
This event is for games only. It is worthwhile to integrate this event into a game type project, as specified in the . In projects with the “app” type, game events will not be tracked and displayed in the interface, even if they are integrated. You can verify and change the project type in Settings → .
This event is for games only. It is worthwhile to integrate this event into a game type project, as specified in the . In projects with the “app” type, game events will not be tracked and displayed in the interface, even if they are integrated. You can verify and change the project type in Settings → .
This event is for games only. It is worthwhile to integrate this event into a game type project, as specified in the . In projects with the “app” type, game events will not be tracked and displayed in the interface, even if they are integrated. You can verify and change the project type in Settings → .
A tutorial is a very important part of any project because the first session lays the foundation for future retention and monetization indicators.
devtodev allows to analyze how users complete the tutorial, find bottlenecks, and measure the time it takes for users to complete the tutorial. These questions can be answered with the help of the Tutorial analysis report.
devtodev is an analytics system designed specifically for game projects. Many game projects have levels, which means that as users become more experienced, they gradually increase their level. In this case levels have a linear structure: the level N is followed by the level N+1.
When players move to the next level, you need to use the LevelUp event. All our reports, that are built by levels, are based on this event, e.g. Currency balances by level, Player levels, etc. Also, if your project has in-game currency, using the LevelUp event you can send information about the current amount of in-game currency players have. This data allows to evaluate the average amount of in-game currency that players have on a particular level.
For example, this is how the Player levels report looks like (see the pic below). It shows how users are distributed among levels, the percentage of users who remain on a particular level, the revenue of a particular level, etc.
There are many projects (for example, Match-3 games), where players attempt to pass a level. Their attempts may be either successful or unsuccessful. In addition, during a certain attempt some numerical indicators can change: the number of stars, resources, in-game currency.
To analyze these attempts, we've created a basic Progression event. In the ProgressionEvent you send information about how players pass a particular game location, whether their attempt was successful, and how numerical indicators change.
Based on the ProgressionEvent, we build the Locations report, where all indicators are calculated by game locations, for successful and unsuccessful attempts.
Many games, especially f2p, have in-game currency. Players can accumulate currency, or buy it for real money. They can then spend it on virtual goods. To work with virtual currency, devtodev has developed the following events:
inAppPurchase – to send information about purchases made by players (please note that these are only purchases made with virtual currency, while information about purchases for real money is sent with the Payment event);
currencyAccrual – to show information about movements of virtual currency (for example, if a player earns currency or receives it for some actions, you can use currencyAccrual to see this information).
All the game economy reports are based on these events.
With the help of the Currency Balances by Level tab in the Economy Balance report (this one also requires a LevelUp event), you can see how users spend, earn and accumulate currency on each game level.
The Top Purchases tab in the Economy Balance report allows you to analyze the structure of the consumer basket and identify items, which are the most popular among different categories of players.
devtodev is a universal analytics system with basic events structure designed specifically for game projects. However, there may be situations when your project requires events that are not provided by devtodev as basic. That's alright, such events can still be sent and analyzed in our system as custom events. It is possible to specify parameter values of custom events. Here are some examples of user actions that can be sent as custom events: when users open an in-game store, click on items, buy items. Based on these events, you can then build a funnel and see the conversion on each step.
Some limits for custom events:
The number of different event types sent from one project shouldn't exceed 300.
The event name must not exceed 72 characters.
One event can contain up to 20 parameters, each of them with unique names of up to 32 symbols.
Parameters can be string and numeric:
the maximum length of parameter values is 255 characters;
the number of string parameter values cannot exceed 50 000; when it exceeds 50 000, the further sending of information about the parameter and possibilities to work with it will be blocked;
Here is some expert advice to avoid problems with limits on custom events:
there is no need to send user IDs in parameters (they are collected by default);
do not send time in the timestamp format (it is also collected by default).
To exclude from statistics transactions made by cheaters, you can use devtodev Anti-cheat service. By using this method, you will be able to check payments for validity before sending them to devtodev. The verification process is the following:
When a user makes a transaction, the anti-cheat method must be called. The integration of this method is described in the documentation for a specific platform (the Anti-cheat methods section).
After this, the transaction will be checked for validity by devtodev.
If the transaction is not valid, the Payment event shouldn't be sent. If the transaction is valid, the Payment event should be sent and it will later get into statistics.
3. Add frameworks:
AppTrackingTransparency.framework
AdSupport.framework
4. Add initialization todidFinishLaunchingWithOptions
method:
An App ID can be found in the settings of the respective app in devtodev (Settings → SDK → Integration → Credentials).
config
- an object instance of DTDAnalyticsConfiguration
, which is used for specifying additional properties during the initialization.
DTDAnalyticsConfiguration
Example:
Create Bridging-Header. To do this, you need to add any swift file to the project (don’t delete it later) and choose ‘Create Bridging Header’ in the offered dialog box.
Make sure that the ‘Build Settings’ for ‘Defines Module’ value evaluates to ‘YES’.
While importing, use: #import <DTDAnalytics/DTDAnalytics-Swift.h>
For SDK to function properly, it needs to be integrated at the earliest moment of the app launch. It is recommended that you use the following method of main entry point initialization:
When developing and publishing apps targeted at children under 13 years old, you need to ensure special conditions for data processing. Any mobile app aimed at children or intended for users in a region with strict regulations on child online protection, must comply with current laws.
If your app has to comply with the legal requirements (COPPA), use the following recommendations:
Implement the coppaControlEnable
method. The method disables collection of ad IDs and vendor IDs (IDFA, IDFV).
Remove AppTrackingTransparency.framework
and all the links pointing to it.
Remove AdSupport.framework
all the links pointing to it.
Call the coppaControlEnable
method before SDK initialization. If the method was not called, the SDK will work as before.
Find the DevToDev.Analytics.Uwp
package using the package manager search engine and click Install. The latest version of the package is recommended.
Initialize the library using the following code:
You can find the App ID in the settings of the respective app in devtodev (Settings → SDK → Integration → Credentials).
config
- is a DTDAnalyticsConfiguration
object instance that is used for specifying additional properties during initialization.
DTDAnalyticsConfiguration
Parameter
Type
Description
currentLevel
Integer
The player level at the moment of devtodev SDK initialization. It’s optional but we recommend using it for improving data accuracy.
userId
String
A custom user ID assigned by the developer. In the case of default calculation by device IDs, the identifier can be used for searching users in devtodev. In case the project uses calculation by user IDs, the parameter is mandatory because it becomes the principal calculation ID in devtodev.
trackingAvailability
DTDTrackingStatus (enum)
The property allows or disallows devtodev tracking of the user. By default, it is set to DTDTrackingStatus.Enable
. SDK stores the previously assigned value. Pass DTDTrackingStatus.Disable
if the user opted out of tracking in line with GDPR.
logLevel
DTDLogLevel (enum)
The level of logging the SDK activity. The DTDLogLevel.no
value is used by default. For troubleshooting during integration it is recommended to set it to DTDLogLevel.Debug
, and either switch it off DTDLogLevel.No
. Use DTDLogLevel.No
in the release version.
Example:
Find the DevToDev.Analytics
package using the package manager search engine and click Install. The latest version of the package is recommended.
Initialize the library using the following code:
You can find the App ID in the settings of the respective app in devtodev (Settings → SDK → Integration → Credentials).
config
- is a DTDAnalyticsConfiguration
object instance that is used for specifying additional properties during initialization.
DTDAnalyticsConfiguration
Parameter
Type
Description
currentLevel
Integer
The player level at the moment of devtodev SDK initialization. It’s optional but we recommend using it for improving data accuracy.
userId
String
A custom user ID assigned by the developer. In the case of default calculation by device IDs, the identifier can be used for searching users in devtodev. In case the project uses calculation by user IDs, the parameter is mandatory because it becomes the principal calculation ID in devtodev.
trackingAvailability
DTDTrackingStatus (enum)
The property allows or disallows devtodev tracking of the user. By default, it is set to DTDTrackingStatus.Enabl
e
. SDK stores the previously assigned value. Pass DTDTrackingStatus.Disable
if the user opted out of tracking in line with GDPR.
logLevel
DTDLogLevel (enum)
The level of logging the SDK activity. The DTDLogLevel.No
value is used by default. For troubleshooting during integration, it is recommended to set it to DTDLogLevel.Debug
, and either switch it off DTDLogLevel.No
or use it only for error handling DTDLogLevel.Error
in the release version.
ApplicationVersion
String
The app version during the devtodev SDK initialization. It is recommended that you set the app version before the initialization to make the collection of app version statistics more precise.
Example:
The SDK can’t control app activity hence this responsibility is passed on to the developer. During the SDK initialization, the activity is triggered automatically, and later the activity status will not change automatically. For tracking app activity, the developer can use the DTDAnalytics.StartActivity
and DTDAnalytics.StopActivity
methods. It is recommended that you use the DTDAnalytics.StopActivity
method to stop the activity when the app goes into the background or being closed. If the window is re-opened from the taskbar it is recommended to renew the activity by using the DTDAnalytics.StartActivity
method.
1.
2. Add DTDAnalytics.xcframework
to the project (with Do Not Embed specified)
USA:
EU:
To comply with
Parameter
Type
Description
currentLevel
int
The player level at the moment of devtodev SDK initialization. It is recommended (but optional) to use to improve data precision.
userId
string
A custom user identifier provided by the developer. If you utilize the default calculation by the device ID, this identifier can be used for finding a user in devtodev.
In case your project utilizes the calculation by the user identifier, you must set this parameter because it becomes the main user identifier in devtodev.
trackingAvailability
DTDTrackingStatus (enum)
The property allows or disallows devtodev tracking of the user. By default, it is set to DTDTrackingStatus.enable
. SDK stores the previously assigned value. Pass DTDTrackingStatus.disable
if the user opted out of tracking in line with GDPR.
logLevel
DTDLogLevel (enum)
The level of logging the SDK activity. The DTDLogLevel.no
value is used by default. For troubleshooting during integration it is recommended to set it to DTDLogLevel.debug
, and either switch it off DTDLogLevel.no
. Use DTDLogLevel.no
in the release version.
Payment event integration and using anti-cheat methods
Here you'll find the principles of processing data about real payments, tips for the integration of the Payment event and anti-cheat methods used in devtodev.
Gross metrics are one of the key indicators of the app’s performance. Therefore, it is important to approach the integration of the Payment event very seriously.
There are four parameters that are sent in the Payment event:
Transaction identifier
Item name
Item price in payment currency
Payment currency identifier.
Let’s look at each of the parameters and things to keep in mind when specifying their values while integrating devtodev SDK.
This is one of the transaction parameters where invalid values occur most often.
Here are the requirements for this parameter:
The transaction identifier is a string value of max 64 symbols. In case this limit is exceeded the value will be shortened to 64 symbols.
The transaction identifier must be unique. Data about the transaction with already registered identifier will be discarded by the system and not included in statistics.
We recommend using the identifier that has been assigned to the transaction by the payment system as the transaction identifier.
In case your app is designed for Apple (iPhone, iPad, iPhone+iPad, or Mac) or Android (Google Play) platforms, the use of the transaction identifier assigned by the app store is mandatory! Transaction identifiers that come from apps on these platforms are checked by devtodev for their compliance with the format used by these markets. This allows us to discard the most obvious cheat transactions. It is also important to know that users who made these transactions are marked as cheaters and all their subsequent transactions are not included in statistics (you can disable this verification process by contacting our managers).
The item name is a string value that shouldn’t exceed 255 symbols. One of the most common mistakes when specifying the value of this parameter is specifying the localized name of the item in multi-language apps, which leads to the appearance of many records that describe the same item in different reports (for example, Purchases by level). One way to avoid this situation is to specify the name of the item bundle as its name.
The item price and currency identifier are related parameters, so it makes sense to describe them in one section. The item price parameter contains the sum that a user paid for the item in a payment currency. The price is specified as a floating-point number. The currency identifier parameter must specify the currency as a three-letter code according to ISO 4217 standard (examples: USD, EUR, JPY, CNY, RUB).
When the Payment event reaches devtodev servers, before transaction data is saved, the sum is automatically converted to USD at the actual currency rate at that moment.
In case of not specifying or specifying invalid currency identifier, the transaction is considered invalid and is not counted in statistics.
If after converting to USD the sum exceeds $1500, the transaction is considered invalid and is not counted in statistics as well (this verification can be disabled by contacting our managers). When the transaction is made with an in-game currency of social network, you first need to convert this currency to any real-world currency.
It is also important to remember that the sum of the purchase sent in the Payment event shows the actual sum that the user paid (this data is used to built Gross metrics). In order to see your net income (Revenue metrics), on the page with app settings in devtodev, you need to specify the coefficient of the part that you get after subtracting the percentage that goes to the platform or publisher. The coefficient can be specified as single or individual for each country (this increases the accuracy in case the part of the sum is spent on taxes and fees that are individual for each country).
Unfortunately, in some situations filling in the parameters of the Payment event is not enough for getting valid data in reports, since there can be cheat transactions. There are several ways to deal with this problem, but all of them are based either on preliminary verification of the transaction or detection of suspicious user actions.
To prevent cheat transactions from getting into the report, you need to either check the transaction in advance and, if the transaction turns out to be invalid, omit sending the Payment event, or mark the user/device as a cheater and exclude their further data from all reports. It is possible to combine both methods for greater reliability.
One of the conditions for increasing the reliability of transaction verification is implementing it outside of the client app. You can create the system of verification and place it on your own servers or use our out-of-the-box solution - devtodev anti-cheat system.
devtodev anti-cheat allows to check the validity of transactions from the following app stores:
iTunes
Google Play Store
Microsoft Store.
At the moment of transaction completion (for example, in the method - (void)paymentQueue:(SKPaymentQueue *) queue updatedTransactions:(NSArray *)
transactions at SKPaymentTransactionObserver class) call the method from the library devtodev.framework [DevToDevCheat verifyPaymentWithCompletion: (void (^)(ReceiptStatus status)) completion];
For example:
To verify the transaction made in Google Play you need:
Application's public key for licensing
Here's how to find your application's public key for licensing:
In the application details page, locate the Services & APIs link and click on it.
In the Services & APIs page, locate the Licensing & In-App Billing section. Your public key for licensing is given in the Your License Key For This Application field.
The example of implementing transaction validation:
Get response about a completed transaction from the payment system.
Either send data about the received transaction for verification by calling devtodev anti-cheat methods or use your own tools for transaction verification.
If the transaction has successfully passed verification, perform the Payment event.
If the transaction hasn’t passed verification, do not perform the Payment event and mark the user as a cheater.
1. Firstly, install CocoaPods using:
2. In the project directory execute the command:
3. In the created Podfile add the dependency:
4. Finally, run the command in your Xcode project directory:
CocoaPods should download and install the devtodev library, and create a new Xcode workspace. Open this workspace in Xcode.
2. Add DTDAnalytics.xcframework
to the project
3. Add frameworks:
AppTrackingTransparency.framework
AdSupport.framework
4. Add initialization todidFinishLaunchingWithOptions
method:
An App ID can be found in the settings of the respective app in devtodev (Settings → SDK → Integration → Credentials).
config
- an object instance of DTDAnalyticsConfiguration
, which is used for specifying additional properties during the initialization.
DTDAnalyticsConfiguration
Example:
Create Bridging-Header. To do this, you need to add any swift file to the project (don’t delete it later) and choose ‘Create Bridging Header’ in the offered dialog box.
Make sure that the ‘Build Settings’ for ‘Defines Module’ value evaluates to ‘YES’.
While importing, use: #import <DTDAnalytics/DTDAnalytics-Swift.h>
For SDK to function properly, it needs to be integrated at the earliest moment of the app launch. It is recommended that you use the following method of main entry point initialization:
When developing and publishing apps targeted at children under 13 years old, you need to ensure special conditions for data processing. Any mobile app aimed at children or intended for users in a region with strict regulations on child online protection, must comply with current laws.
If your app has to comply with the legal requirements (COPPA), use the following recommendations:
Implement the coppaControlEnable
method. The method disables collection of ad IDs and vendor IDs (IDFA, IDFV).
Remove AppTrackingTransparency.framework
and all the links pointing to it.
Remove AdSupport.framework
all the links pointing to it.
Call the coppaControlEnable
method before SDK initialization. If the method was not called, the SDK will work as before.
The Privacy Manifest describes the methods for ensuring code confidentiality in the application in a unified format. When publishing the application, Xcode will combine the privacy manifests of all third-party SDKs used in your application into a single, convenient report. This report makes it easier to create more accurate privacy labels (Nutrition Labels).
The Privacy Manifest includes the following sections for data entry:
Privacy Tracking Enabled
Privacy Tracking Domains
Privacy Nutrition Label Types
Privacy Accessed API Types
Privacy Tracking Enabled. A Boolean value indicating whether the application or third-party SDK uses data for tracking, as defined within the App Tracking Transparency framework.
Privacy Tracking Domains. An array of strings listing the internet domains that the application or third-party SDK connects to and participates in tracking.
Privacy Nutrition Label Types. An array of dictionaries describing the types of data collected by the application or third-party SDK. Nutrition Labels are needed to let users know what data the application collects before installing it from the App Store.
Privacy Accessed API Types. An array of dictionaries describing the types of APIs accessed by the application or third-party SDK, which are marked as APIs and require verification for access.
Privacy Nutrition Label Types
Privacy Accessed API Types
Privacy Nutrition Label Types
Privacy Accessed API Types
Since we distribute our SDKs as binary dependencies, we have implemented a signing practice. Now, when you use a new version of the SDK, Xcode will confirm that it has been signed by us, increasing the integrity of the software supply chain.
The process of detecting cheaters based on their behavior within apps depends on the specificity of a particular app. If you have implemented such an algorithm, you can mark suspicious users as cheaters to avoid getting data on their payments in reports. To do that, you just need to execute a or mark users via API (“” section).
The validation process requires full values of the keys INAPP_PURCHASE_DATA и INAPP_DATA_SIGNATURE
Go to the and sign in. Make sure that you sign in to the account from which the application you are licensing is published (or will be published).
The receipt is taken from the result of implementing the following method -
is the easiest way to add devtodev into your iOS project.
1.
USA:
EU:
To comply with
The Privacy Manifest is a new way introduced at for third-party SDK developers to provide information about their privacy policies.
Parameter
Type
Description
currentLevel
int
The player level at the moment of devtodev SDK initialization. It is recommended (but optional) to use to improve data precision.
userId
string
A custom user identifier provided by the developer. If you utilize the default calculation by the device ID, this identifier can be used for finding a user in devtodev.
In case your project utilizes the calculation by the user identifier, you must set this parameter because it becomes the main user identifier in devtodev.
trackingAvailability
DTDTrackingStatus (enum)
The property allows or disallows devtodev tracking of the user. By default, it is set to DTDTrackingStatus.enable
. SDK stores the previously assigned value. Pass DTDTrackingStatus.disable
if the user opted out of tracking in line with GDPR.
logLevel
DTDLogLevel (enum)
The level of logging the SDK activity. The DTDLogLevel.no
value is used by default. For troubleshooting during integration it is recommended to set it to DTDLogLevel.debug
, and either switch it off DTDLogLevel.no
. Use DTDLogLevel.no
in the release version.
Product Interaction
No
No
Analytics
Device ID
No
No
Analytics
User ID
No
No
Analytics
Purchase History
No
No
Analytics
Other Data Types
No
No
Analytics
User Defaults
CA92.1: Access info from same app, per documentation
Device ID
No
No
Analytics
Other Data Types
No
No
Analytics
User Defaults
CA92.1: Access info from same app, per documentation
Then fill out the registration form.
You will receive an email to confirm your registration.
Please do the following to integrate your web application with devtodev:
1. Add the application to the Space using the wizard for adding applications.
2. To integrate SDK, add the following line to the tag of your page:
3. Init the SDK.
In order for SDK for WEB to start working, it is necessary to perform initialization right after the page is loaded and you have a basic user identifier at your disposal.
You can find the App ID in the settings of the respective app in devtodev (Settings → SDK → Integration → Credentials).
config
- is an object that is used for specifying additional properties during initialization.
Config
Example:
First of all, visit our website and click 'Sign up'.
Since there’s no option to get any consistent identifier in web browsers, we recommend using as a User ID either a social network ID with your app or an ID that your server assigns to a user. It’s best to assign a User ID and specify it in the config
object during the SDK initialization instead of using a method after the initialization.
If you have a games app, we recommend specifying the current player’s lever either in the config
or at the earliest possible moment after the initialization via the method.
Parameter
Type
Description
userId
string
Unique user identifier. For example, user’s ID in a social network, or a unique account name used for user identification on your server. If at the time of initialization this identifier is not yet available, specify the identifier later using
the setUserId
method.
currentLevel
integer
The player level at the moment of devtodev SDK initialization. Must be greater than 0. It’s optional but we recommend using it for improving data accuracy.
trackingAvailability
boolean
The property allows or disallows devtodev tracking of the user. By default, it is set to true
. SDK stores the previously assigned value. Pass false if the user opted out of tracking in line with GDPR.
logLevel
string
The level of logging the SDK activity. The "No
" value is used by default. For troubleshooting during integration, it is recommended to set it to "Debug
", and either switch it "No
" or use it only for error handling "Error
" in the release version.
applicationVersion
String
The app version. Cannot be empty.
To integrate devtodev analytics SDK, you can use one of the two methods: by using the Unity Package Manager (recommended) or by manually importing the unitypackage.
If you integrated the devtodev package manually, then you need to delete the Assets/DevToDev and Plugins/DevToDev folders.
Open the Package Manager (Window → Package Manager), click + in the top left corner and select Add package from git URL.
Wait for the Unity Package Manager to download the package.
In the Unity Editor menu, open Assets → Import Package → Custom Package
Select the DTDAnalytics.unitypackage that you have just downloaded
Click Import
Create a script with the following code and attach it to the GameObject
that will survive the entire life cycle of the app.
You can find the AppID in the settings of the respective app in devtodev (Settings → SDK → Integration → Credentials).
config
- an object instance of DTDAnalyticsConfiguration
, which is used for specifying additional properties during the initialization.
DTDAnalyticsConfiguration
Parameter
Type
Description
CurrentLevel
Integer
The player level at the moment of devtodev SDK initialization. It’s optional but we recommend using it for improving data accuracy.
UserId
String
A custom user ID assigned by the developer. In the case of default calculation by device IDs, the identifier can be used for searching users in devtodev. In case the project uses calculation by user IDs, the parameter is mandatory because it becomes the principal calculation ID in devtodev.
TrackingAvailability
DTDTrackingStatus (enum)
The property allows or disallows devtodev tracking of the user. By default, it is set to DTDTrackingStatus.Enable
. SDK stores the previously assigned value. Pass DTDTrackingStatus.Disable
if the user opted out of tracking in line with GDPR.
LogLevel
DTDLogLevel (enum)
The level of logging the SDK activity. The DTDLogLevel.no
value is used by default. For troubleshooting during integration it is recommended to set it to DTDLogLevel.Debug
, and either switch it off DTDLogLevel.No
. Use DTDLogLevel.No
in the release version.
ApplicationVersion
String
The app version during the devtodev SDK initialization. Use the property on the WinStandalone platform only. For all other platforms, data is collected automatically.
Example:
SDK Activity
The SDK can’t control app activity in case you use Windows Standalone therefore this responsibility is shifted to the developer. While initializing the SDK, the activity starts automatically and after that, the activity status will not auto-change. To track app activity, the developer can use the following methods: DTDAnalytics.StartActivity
and DTDAnalytics.StopActivity
. It is recommended to use the DTDAnalytics.StopActivity
method to stop activity when the app goes into the background or gets closed. You can use the DTDAnalytics.StartActivity
method to resume activity when the app gets reopened from the taskbar.
For other platforms, there is no need to manually call the DTDAnalytics.StartActivity
and DTDAnalytics.StopActivity
methods.
If you imported the DTDGoogle package, delete the imported files Assets\Plugins\DevToDev\Android\DTDGoogleAndroid.dll and Assets\DevToDev\Analytics\Editor\GoogleDependencies.xml
In the assets/Plugins/Android/ folder create a settingsTemplate.gradle file with the following content:
Open Window → devtodev and select Create android plugin folder
Copy the “agconnect-services.json“ file to the Assets\Plugins\Android\devtodev.plugin folder
Open Assets → External Dependency Manager → Android ResolverAssets → External Dependency Manager → Android Resolver and click Resolve
To integrate with Xcode, the SDK uses PostProcessBuild
in the DTDPostProcessAnalytics
and DTDPostProcessMessaging
scripts. If you use custom PostProcessBuild
scripts, add them callbackOrder
of less than 98
to avoid conflicts.
When developing and publishing apps targeted at children under 13 years old, you need to ensure special conditions for data processing. Any mobile app aimed at children or intended for users in a region with strict regulations on child online protection, must comply with current laws.
If your app has to comply with the legal requirements (COPPA), use the following recommendations:
Implement the CoppaControlEnable
method. The method disables collection of ad IDs and vendor IDs (IDFA, IDFV).
AppTrackingTransparency.framework
and all the links pointing to it.
AdSupport.framework
and all the links pointing to it.
Set IS_COPPA_ENABLED = true
in DTDPostProcessAnalytics.cs
(Assets/DevToDev/Analytics/Editor
)
Implement the CoppaControlEnable
method. The method disables collection of ad IDs and vendor IDs.
If you are using DTDGoogle or DTDHuawei from Unity Package Manager, disable it.
If you are using DTDGoogle.unitypackage, remove the following files:
If you are using DTDHuawei.unitypackage, remove the following files:
Call the CoppaControlEnable
method before SDK initialization. If the method was not called, the SDK will work as before.
Copy the repository URL to the input box and click Add.
If you work with SDK version 3.5.0 and above, and you want to use Google Ad ID, you need to add . When developing and publishing apps for kids , you do not need . Read more about working with in the .
If you work with SDK version 3.5.0 and above, and you want to use Huawei Ad ID, you need to add . When developing and publishing apps for kids , you do not need . Read more about working with in the .
You can pick a specific SDK version by adding # and a version number at the end of the URL, for example: #v3.3.2
Download DTDAnalytics.unitypackage from
If you work with SDK version 3.5.0 and above, and you want to use Google Ad ID, you need to import the DTDGoogle.unitypackage. When developing and publishing apps for kids , you do not need the DTDGoogle.unitypackage. Read more about working with in the .
If you work with SDK version 3.5.0 and above, and you want to use Huawei Ad ID, you need to import the DTDHuawei.unitypackage. When developing and publishing apps for kids , you do not need the DTDHuawei.unitypackage. Read more about working with in the .
To resolve external android dependencies, you need to use .
Add the following strings to proguard.txt ():
Select your project in In the “General information” section find “App information” and download the “agconnect-services.json“ file.
Import the DTDHuawei.unitypackage manually from or use Unity Package Manager with .
To add the following rule:
Your app must request tracking authorization before it can get the advertising identifier. See on how to request it.
At Apple introduced new privacy manifests and xcframework signature. More information about it can be found .
USA:
EU:
To comply with , remove from Xcode project:
Session Measurement and Tracking in Mobile and Web Applications
Session measurement is an important metric for product analysis as it allows us to determine how frequently and for how long users interact with our website or application. However, it is important to note that session tracking methods on mobile and web applications have their own peculiarities. When a user starts a session in the application, the SDK recognizes that the application is active, indicating that it has gained focus (when the app is brought into the foreground). If the last recorded activity was more than 10 minutes ago, a Session Start event is sent.
Application activity refers to the period of time when the application is in focus, meaning the application or web page is open and the device screen is active. The focus is lost if the application goes into the background or if another website is opened in the current tab.
We measure the duration of application activity using a technical event called User Engagement (UE). It starts counting the time as soon as the application receives focus and sends the activity counter data to the server.
If, for any reason, the information about the duration of the activity couldn't be sent, it will be sent the next time the application is initialized and has internet access. However, the activity will only be included in devtodev reports if it has been less than 7 days since the session, as events from a previous period more than 7 days ago are ignored.
Thus, we have information about "Session start" and the duration of activity, but there is no specific "Session end" event. All events performed by the user are marked with the session start date in which they occurred (sessionid field in SQL tables)
For mobile applications, it is difficult to determine the beginning and end of a session because users often switch between screens of different applications. If an application on a mobile device receives focus and the last active time (in focus) was more than 10 minutes ago, a new session will be started and an event will be sent to devtodev.
For example, the user opens the application, spends a minute in it, and then puts the application in the background, a Session Start event will be sent to devtodev in the first second. After a minute, when the application goes into the background or is closed, an event with information about the duration of activity (UE) will be sent to the server as the focus is lost.
For web projects, it is not possible to detect when the user closes the page. Therefore, the UE event (duration of activity) is sent to the server every 2 minutes. To minimize the loss of information about the session duration to no more than two minutes in case of session termination, the SDK additionally saves the duration every 5 seconds and will send the information about the last duration upon the next activity. If there is no next session, the information about the last two minutes may be lost.
Let's consider an example where a user opens a webpage, spends 1.5 minutes on it, then opens another page on the site and spends another 1.5 minutes there. In devtodev, a Session Start event will be sent in the first second, and every 5 seconds, information about the activity will be saved. After 2 minutes from the start of the session, a UE event with 2 minutes of activity will be sent to the server, and after the third minute, the activity of 1 minute will be recorded in the Local Storage. Information about this activity will be sent during the next user session. The metric Average session length is calculated from the data obtained from session starts and user activity time during those sessions. It is defined as the sum of the length of all sessions divided by the number of sessions within a given period
In Basic Metrics, Engagement-> Sessions, and other reports, we encounter the following metrics:
Session duration: Shows the average session time of one user. It is calculated as (Total Sessions Length / Number of sessions) averaged by users Number of sessions: Shows the average number of sessions per user. It is calculated as the Number of sessions divided by the Number of users Total daily time spent: Represents the average total time per day spent in the user application. It is calculated as Total Sessions Length divided by the number of Active Users Sessions: Sessions by user shows the average number of sessions made by one user during the period Sessions by user: It shows the average number of sessions made by one user during the period
For the calculation of the necessary metrics:
In the SQL wizard, there is a parameter called session.Duration, which is tracked by the UE event. The session.Duration parameter represents the duration of the activity, i.e., the time the application is in focus, and it is not equal to the session duration.
sessions.Count is the number of Session Start received from the user
Table .sessions has two types of eventtype field in SQL: ss: represents the Session Start event received from the user ue: represents the time that the application was in focus (active), providing information about time parameters and activity duration.
From this data, you can calculate the average session length by dividing the sum of activity lengths from all rows for the desired period by the sum of all session starts for the same period. We recommend using extended time periods to obtain a more reliable result.
For a C++ project type, add the DTDAnalytics
name to the list of dependency module names to the <module_name>.Build.cs file of the module in which you plan to use the plugin.
Example:
A class that implements analytic methods.
Header file:
A class that implements user card methods.
The class header:
SDK tracking status.
Header file:
Values:
Unknown = 0
- leave tracking unchanged
Enable = 1
- tracking enabled
Disable = 2
- tracking disabled
Example:
SDK logging level.
Header file:
Values:
Unknown = 0
- leave logging level unchanged
No = 1
- logging disabled
Error = 2
- logging of errors
Warning = 3
- logging of warnings and errors
Info = 4
- logging of information messages, warnings and errors
Debug = 5
- logging of debugging messages, informational messages, warnings and errors
Example:
Types of resource accumulation.
Header file:
Values:
Earned = 0
- earned resources
Bought = 1
- purchased resources
Example:
Predefined social media.
Header file:
Values:
Facebook = 0
Vkontakte = 1
Twitter = 2
Googleplus = 3
Whatsapp = 4
Viber = 5
Evernote = 6
Googlemail = 7
Linkedin = 8
Pinterest = 9
Reddit = 10
Renren = 11
Tumblr = 12
Qzone = 13
Example:
User gender.
Header file:
Values:
Unknown = 0
Male = 1
Female = 2
Example:
Referral properties.
Header file:
Values:
Source = 0
Medium = 1
Content = 2
Campaign = 3
Term = 4
Example:
An optional parameter of int32 type
Header file:
HasValue
bool
Option label
Value
int32
Parameter value
For your convenience, we implemented the conversion constructor:
Example:
An optional parameter of FString type.
Header file:
HasValue
bool
Option label
Value
FString
Parameter value
For your convenience, we implemented the conversion constructor:
Example:
Configuration of the analytics plugin.
Header file:
LogLevel
EDTDLogLevel
Logging level
CurrentLevel
FDTDOptionalInt32
Current level
UserId
FDTDOptionalString
User ID
ApplicationVersion
FDTDOptionalString
Application version (Windows)
TrackingAvailability
EDTDTrackingStatus
Tracking settings
Example:
Custom parameters of a custom event.
Header file:
StringParameters
TMap<FString, FString>
String parameters
IntParameters
TMap<FString, int64>
Integer parameters
FloatParameters
TMap<FString, float>
Real parameters (floating-point numbers)
BoolParameters
TMap<FString, bool>
Boolean parameters
Example:
Parameters of the progression start event.
Header file:
Difficulty
FDTDOptionalInt32
Difficulty
Source
FDTDOptionalString
Source
Example:
Parameters of the progression completion event.
Header file:
SuccessfulCompletion
bool
Successful completion of the progression (‘false’ by default)
Duration
int32
Duration (if 0, duration is calculated automatically)
Spent
TMap<FString, int64>
Resources spent
Earned
TMap<FString, int64>
Resources earned
Example:
Header file:
Definitions:
appKey
FString
You can find it in the settings of the corresponding application in devtodev (Settings → SDK → Integration → Credentials)
appKey
FString
You can find it in the settings of the corresponding application in devtodev (Settings → SDK → Integration → Credentials)
config
FDTDAnalyticsConfiguration
Initialization parameters
The DevToDev SDK extends the Godot engine in a modular way and supports platforms: MacOS, iOS, Android.
To work in the Godot editor, compile the engine source code and the analytics module:
For initialization, add the following code at the start of your application:
You can find the AppID in the settings of the respective app in devtodev (Settings → SDK → Integration → Credentials).
config
- an object instance of GDDTDAnalyticsConfiguration
, which is used for specifying additional properties during the initialization
Example:
Open the Export Template Manager to download and install templates:
The next step is to prepare a custom template as a macos.zip archive. Don't forget to add the DTDAnalytics native library, copy libDTDAnalytics.dylib
to macos_template.app/Contents/MacOS/
.
Open the Export menu and specify the path to the prepared custom template:
Open the Export Template Manager to download and install templates:
The next step is to prepare a custom template as an ios.zip archive. Don't forget to add the DTDAnalytics native library, copy DTDAnalytics.xcframework
to ios_xcode/
.
In XCode project:
Add DTDAnalytics.xcframework
to the project (with Do Not Embed specified)
Create Bridging-Header. To do this, add any swift file to the project (don't delete it later) and select 'Create Bridging Header' in the dialogue box that appears.
Add frameworks:
AppTrackingTransparency.framework
AdSupport.framework
Сlick to install android templates:
After installing the template, an android folder will appear in your project.
Move the d2d_analytics/native/androidAnalytics.aar
to the android/plugins/ folder
in your project. You will also need to create an Analytics.gdap
file in android/plugins/
with the following content:
Next, Analytics should appear in the Plugins section, check it out:
After successful compilation execute the following commands:
In the next step in godot-4.0-stable/bin
you will see godot-lib.template_debug.aar
or
godot-lib.template_relaese.aar
.
You need to copy and replace this file to the previously installed template in your project at the path:
appName/android/build/libs/debug
- for debugging
appName/android/build/libs/release
- for release
After these steps, you are ready to export your Android app.
Make sure that Use Gradle Build
(in the Gradle Build section), Analytics
(in the Plugins section) and the previously compiled Architecture
(in the Architectures section) are selected.
The SDK is available in . Download the of latest release. Unzip the archive and copy DTDAnalytics folder to the Plugins folder of your project.
Godot engine 4.0+ ()
.
build system.
SDK module source code ()
The SDK module is available in . Download the Source code of latest release and copy d2d_analytics folder to the modules(/godot/modules/
) folder of Godot engine source code.
Open a terminal, go to the root directory of the engine source code. Compile a custom template for MacOS (see for MacOS), select Debug or Release build and processor architecture. To support both architectures in a single Universal 2 binary, use lipo:
Open a terminal, go to the root directory of the engine source code. And compile a custom template for iOS (see for iOS). To work with the iOS simulator, compile the sources with the ios_simulator=yes
flag. To support both architectures in a single Universal 2 binary, use lipo:
The next step is to compile the Godot engine for Android (see ), choose debug or release build, and select the processor architecture.
Parameter
Type
Description
CurrentLevel
Integer
The player level at the moment of devtodev SDK initialization. It’s optional but we recommend using it for improving data accuracy.
UserId
String
A custom user ID assigned by the developer. In the case of default calculation by device IDs, the identifier can be used for searching users in devtodev. In case the project uses calculation by user IDs, the parameter is mandatory because it becomes the principal calculation ID in devtodev.
TrackingAvailability
GDDTDTrackingStatus (enum)
The property allows or disallows devtodev tracking of the user. By default, it is set to GDDTDTrackingStatus.Enable
. SDK stores the previously assigned value. Pass GDDTDTrackingStatus.Disable
if the user opted out of tracking in line with GDPR.
LogLevel
GDDTDLogLevel (enum)
The level of logging the SDK activity. The GDDTDLogLevel.No
value is used by default. For troubleshooting during integration it is recommended to set it to GDDTDLogLevel.Debug
, and either switch it off GDDTDLogLevel.No
. Use GDDTDLogLevel.No
in the release version.
The event is used for individual tracking of ad revenue on user devices. The method is used if there are CPI data available on the client device (they can be obtained from the ad network SDK).
network
String
from 1 to 100 symbols
Name of the ad network responsible for the impression
revenue
Double
from 0,0 to Double.max
Reward for banner display in USD
placement
String?
from 1 to 100 symbols, optional
Banner placement
unit
String?
from 1 to 100 symbols, optional
Banner name
network
NSString
from 1 to 100 symbols
Name of the ad network responsible for the impression
revenue
double
from 0,0 to Double.max
Reward for banner display in USD
placement
NSString _Nullable
from 1 to 100 symbols, optional
Banner placement
unit
NSString _Nullable
from 1 to 100 symbols, optional
Banner name
network
String
from 1 to 100 symbols
Name of the ad network responsible for the impression
revenue
Double
from 0,0 to Double.max
Reward for banner display in USD
placement
String?
from 1 to 100 symbols, optional
Banner placement
unit
String?
from 1 to 100 symbols, optional
Banner name
network
String
from 1 to 100 symbols
Name of the ad network responsible for the impression
revenue
Double
from 0,0 to Double.max
Reward for banner display in USD
placement
String?
from 1 to 100 symbols, optional
Banner placement
unit
String?
from 1 to 100 symbols, optional
Banner name
network
String
from 1 to 100 symbols
Name of the ad network responsible for the impression
revenue
Double
from 0,0 to Double.max
Reward for banner display in USD
placement
String?
from 1 to 100 symbols, optional
Banner placement
unit
String?
from 1 to 100 symbols, optional
Banner name
network
String
from 1 to 100 symbols
Name of the ad network responsible for the impression
revenue
Double
from 0,0 to Double.max
Reward for banner display in USD
placement
String?
from 1 to 100 symbols, optional
Banner placement
unit
String?
from 1 to 100 symbols, optional
Banner name
Parameter
Type
Restrictions
Description
socialNetwork
FString
from 1 to 100 symbols
The name of the ad network that delivered the impression.
revenue
float
form 0.0 to float.MaxValue
Reward for displaying a banner in USD.
placement
FString
from 1 to 100 symbols
Placement of the banner.
unit
FString
from 1 to 100 symbols
Banner title.
network
String
from 1 to 100 symbols
Name of the ad network responsible for the impression
revenue
Float
from 0,0 to Double.max
Reward for banner display in USD
placement
String
from 1 to 100 symbols, optional
Banner placement
unit
String
from 1 to 100 symbols, optional
Banner name
The event is used to track connections to social media channels.
Use the following constants to specify a social network:
.facebook, .vkontakte , .twitter, .googleplus, .whatsapp, .viber, .evernote, .googlemail, .linkedin, .pinterest, .qzone, .reddit, .renren, .tumblr
Or create an object with the desired social media name.
Use the following constants to specify a social network:
.facebook, .vkontakte , .twitter, .googleplus, .whatsapp, .viber, .evernote, .googlemail, .linkedin, .pinterest, .qzone, .reddit, .renren, .tumblr
Or create an object with the desired social media name.
Use the following constants to specify a social network:
DTDSocialNetwork.facebook, DTDSocialNetwork.vkontakte , DTDSocialNetwork.twitter, DTDSocialNetwork.googleplus, DTDSocialNetwork.whatsapp, DTDSocialNetwork.viber, DTDSocialNetwork.evernote, DTDSocialNetwork.googlemail, DTDSocialNetwork.linkedin, DTDSocialNetwork.pinterest, DTDSocialNetwork.qzone, DTDSocialNetwork.reddit, DTDSocialNetwork.renren, DTDSocialNetwork.tumblr
Or create an object with the desired social media name.
Use the following constants to specify a social network:
DTDSocialNetwork.Companion.getFacebook(), DTDSocialNetwork.Companion.getVkontakte(), DTDSocialNetwork.Companion.getTwitter(), DTDSocialNetwork.Companion.getGoogleplus(), DTDSocialNetwork.Companion.Whatsapp(), DTDSocialNetwork.Companion.getViber(), DTDSocialNetwork.Companion.getEvernote(), DTDSocialNetwork.Companion.getGooglemail(), DTDSocialNetwork.Companion.getLinkedin(), DTDSocialNetwork.Companion.getPinterest(), DTDSocialNetwork.Companion.getQzone(), DTDSocialNetwork.Companion.getReddit(), DTDSocialNetwork.Companion.getRenren(), DTDSocialNetwork.Companion.getTumblr()
Or create an object with the desired social media name.
Use the following constants to specify a social network:
DTDSocialNetwork.facebook, DTDSocialNetwork.vkontakte , DTDSocialNetwork.twitter, DTDSocialNetwork.googleplus, DTDSocialNetwork.whatsapp, DTDSocialNetwork.viber, DTDSocialNetwork.evernote, DTDSocialNetwork.googlemail, DTDSocialNetwork.linkedin, DTDSocialNetwork.pinterest, DTDSocialNetwork.qzone, DTDSocialNetwork.reddit, DTDSocialNetwork.renren, DTDSocialNetwork.tumblr
Or create an object with the desired social media name:
Use the following constants to specify a social network:
DTDSocialNetwork.facebook, DTDSocialNetwork.vkontakte , DTDSocialNetwork.twitter, DTDSocialNetwork.googleplus, DTDSocialNetwork.whatsapp, DTDSocialNetwork.viber, DTDSocialNetwork.evernote, DTDSocialNetwork.googlemail, DTDSocialNetwork.linkedin, DTDSocialNetwork.pinterest, DTDSocialNetwork.qzone, DTDSocialNetwork.reddit, DTDSocialNetwork.renren, DTDSocialNetwork.tumblr
Or create an object with the desired social media name:
Argument
Type
Description
socialNetwork
EDTDSocialNetwork
Predefined social network.
Or use special method for custom social network:
Argument
Type
Description
socialNetwork
FString
Custom social network.
Use the following constants to specify a social network:
.facebook, .vkontakte , .twitter, .googleplus, .whatsapp, .viber, .evernote, .googlemail, .linkedin, .pinterest, .qzone, .reddit, .renren, .tumblr
Or create an object with the desired social media name.
Track social media posts and analyze their effectiveness and virality. Pass the event after the post has been approved by social media.
Argument
Type
Description
socialNetwork
EDTDSocialNetwork
Predefined social network.
Argument
Type
Description
socialNetwork
FString
Custom social network.
If you have referral information, you can pass it using the following method:
Argument
Type
Description
utmData
TMap<EDTDReferralProperty, FString>
UTM data.
To send an event packet before it is full (10 events, by default) or before the end of the period of its formation (2 minutes, by default), you can use immediate dispatch.
For example:
Argument
Type
Description
onResult
FAnalyticsDynamicGetterStringDelegate
FDTDGetterStringDelegate
Callback.
This method denies/allows tracking of user data and also implements the right to be forgotten in accordance with the requirements of the GDPR.
When this method is called with the 'false' value, the SDK sends a command to the server to delete all personal user data that was collected by devtodev in this application, blocking further user data collection.
The user will remain in the devtodev system only as an impersonal unit in the previously aggregated metrics.
If it is set to ‘true', tracking can be enabled again. In this case, the user will be considered new.
To enable/disable user tracking by the devtodev system. Bool type.
Get device ID. String type.
Argument
Type
Description
onResult
FAnalyticsDynamicGetterStringDelegate
FDTDGetterStringDelegate
Callback.
Get the version of the integrated devtodev SDK. String type.
Argument
Type
Description
onResult
FAnalyticsDynamicGetterStringDelegate
FDTDGetterStringDelegate
Callback.
Retrieving the saved state of the user tracking permission by the devtodev system. See “Setting User Tracking Status”. Bool type.
Argument
Type
Description
onResult
FAnalyticsDynamicGetterBoolDelegate
FDTDGetterBoolDelegate
Callback.
devtodev ID is the primary numeric identifier for the device/user account in the devtodev database. Using devtodev ID, you are sure to find the user in devtodev.
The identifier will be received from the server some time after the initialization of the SDK.
If you have set counting by users, a separate devtodev id will be issued for each device user.
To obtain the devtodev ID, you need to pass the listener to DTDAnalytics
:
The delegate must implement the func didReceiveDevtodevId(with devtodevId: Int)
The didReceiveDevtodevId
method will be called with every ID change on the server side.
To obtain the devtodev ID, you need to pass the listener to DTDAnalytics
:
The delegate must implement the (void)didReceiveDevtodevIdWith:(NSInteger)devtodevId;
The didReceiveDevtodevId
method will be called with every ID change on the server side.
To obtain the devtodev ID, you need to pass the DTDIdentifiersListener
listener to DTDAnalytics
:
The didReceiveDevtodevId
method will be called with every ID change on the server side.
To obtain the devtodev ID, you need to pass the DTDIdentifiersListener
listener to DTDAnalytics
:
The didReceiveDevtodevId
method will be called with every ID change on the server side.
To obtain the devtodev ID, you need to pass the DTDIdentifiersListener
listener delegate to DTDAnalytics
:
The delegate
method will be called with every ID change on the server side.
To obtain the devtodev ID, you need to pass the DTDIdentifiersListener
listener delegate to DTDAnalytics
:
The delegate
method will be called with every ID change on the server side.
Argument
Type
Description
listener
FAnalyticsDynamicGetterLongDelegate
FDTDGetterLongDelegate
devtodev ID Listener.
To obtain the devtodev ID, you need to pass the Callable
to DTDAnalytics
:
The didReceiveDevtodevId
method will be called with every ID change on the server side.
To receive a callback when the SDK initialization is complete, you can use a method that will implement the initialization callback. When the SDK completes the initialization, the callback will be called on the main application thread.
Get response about a completed transaction from the payment system.
Either send data about the received transaction for verification by calling devtodev anti-cheat methods or use your own tools for transaction verification.
If the transaction has successfully passed verification, perform the Payment event.
If the transaction hasn’t passed verification, do not perform the Payment event and mark the user as a cheater.
The devtodev service allows you to validate transactions to prevent fraud from influencing your statistics. For this, you need to integrate DTDAntiCheat
module.
We strongly discourage you from using verification results for deciding on allowing or denying users to receive their purchases! Employ this method exclusively for preventing fraud transaction data from being sent to devtodev!
This method is used to initialize the user in applications where you have set calculation by user ID specified by the developer, applications that are part of a cross-platform project.
You can also use this method when calculating by device ID (by default) to pass in the user ID used on your servers so that you can easily find the user on devtodev.
This method is used in very rare cases. It is applicable in the case when the calculation of users in the project is carried out by the user ID specified by the developer. In this case, the application can change this identifier. For example, calculation in the application is carried out by user emails and in the application, it is possible to change this email to another one. At the time of replacement, you need to call this method, specifying the user's previous email and the one with which it was replaced.
Do not use this method to re-login as a different user! The setUserId method is used for relogging.
This method is used in cross-platform and data synchronized applications. The method is required to update user level data.
To set the current value to the user level, use setCurrentLevel(currentLevel: Int)
method:
We recommend that you use the setCurrentLevel
method immediately after using the setUserID
method or specify the current user level in the initialization configuration (the level property of an instance of the DTDAnalyticsConfiguration
).
Do not use the setCurrentLevel
method when the user reaches a new level. In this case, you must use the levelUp
method.
To get the user-level value stored by the SDK, use getCurrentLevel(completionHandler: @escaping (Int) -> Void)
method
To set the current value to the user level, use (void)currentLevel:(NSInteger)currentLevel;
method:
We recommend that you use the setCurrentLevel
method immediately after using the setUserID
method or specify the current user level in the initialization configuration (the level property of an instance of the DTDAnalyticsConfiguration
).
Do not use the setCurrentLevel
method when the user reaches a new level. In this case, you must use the levelUp
method.
To get the user-level value stored by the SDK, use (void)currentLevelHandler:( void (^ _Nonnull)(NSInteger))completionHandler;
method
To set the current value to the user level, use method:
We recommend that you use the setCurrentLevel
method immediately after using the setUserID
method or specify the current user level in the initialization configuration (the level property of an instance of the DTDAnalyticsConfiguration
).
Do not use the setCurrentLevel
method when the user reaches a new level. In this case, you must use the levelUp
method.
To get the user-level value stored by the SDK, use getCurrentLevel(completionHandler: @escaping (Int) -> Void)
method
To set the current value to the user level, use method:
We recommend that you use the setCurrentLevel
method immediately after using the setUserID
method or specify the current user level in the initialization configuration (the level property of an instance of the DTDAnalyticsConfiguration
).
Do not use the setCurrentLevel
method when the user reaches a new level. In this case, you must use the levelUp
method.
To get the user-level value stored by the SDK, use getCurrentLevel(completionHandler: @escaping (Int) -> Void)
method
To set the current value to the user level, use method:
We recommend that you use the SetCurrentLevel
method immediately after using the SetUserID
method or specify the current user level in the initialization configuration (the level property of an instance of the DTDAnalyticsConfiguration
).
Do not use the SetCurrentLevel
method when the user reaches a new level. In this case, you must use the LevelUp
method.
To get the user-level value stored by the SDK, use GetCurrentLevel
method:
To set the current value to the user level, use method:
We recommend that you use the SetCurrentLevel
method immediately after using the SetUserID
method or specify the current user level in the initialization configuration (the level property of an instance of the DTDAnalyticsConfiguration
).
Do not use the SetCurrentLevel
method when the user reaches a new level. In this case, you must use the LevelUp
method.
To get the user-level value stored by the SDK, use GetCurrentLevel
method:
To set the current value to the user level, use method:
We recommend that you use the setCurrentLevel
method immediately after using the setUserID
method or specify the current user level in the initialization configuration (the level property of an instance of the DTDAnalyticsConfiguration
).
Do not use the setCurrentLevel
method when the user reaches a new level. In this case, you must use the levelUp
method.
To get the user-level value stored by the SDK, use getCurrentLevel
method.
To set the current value to the user level, use method:
We recommend that you use the SetCurrentLevel
method immediately after using the SetUserID
method or specify the current user level in the initialization configuration (the level property of an instance of the EDTDAnalyticsConfiguration
).
Do not use the SetCurrentLevel
method when the user reaches a new level. In this case, you must use the LevelUp
method.
To get the user-level value stored by the SDK, use method:
To set the current value to the user level, use SetCurrentLevel(level: int)
method:
We recommend that you use the SetCurrentLevel
method immediately after using the SetUserID
method or specify the current user level in the initialization configuration (the level property of an instance of the GDDTDAnalyticsConfiguration
).
Do not use the SetCurrentLevel
method when the user reaches a new level. In this case, you must use the LevelUp
method.
To get the user-level value stored by the SDK, use GetCurrentLevel(onResult: Callable)
method
If you have your own methods for detecting cheaters in the application, you can tag such users. Actions taken by these users will not be counted in statistics.
Attention! These properties have been removed since the devtodev SDK versions: iOS & macOS 2.4.0, Android 2.5.0, Unity SDK 3.8.0, Godot 1.0.0.
Attention! We strongly discourage the storage of personal user data! If you plan to pass this data, be sure to indicate this in the ‘Nutrition label’ when submitting the application to the App Store review.
Attention! We strongly discourage the storage of personal user data! If you plan to pass this data, be sure to indicate this in the ‘Nutrition label’ when submitting the application to the App Store review.
Attention! We strongly discourage the storage of personal user data! If you plan to pass this data, be sure to indicate this in the ‘Nutrition label’ when submitting the application to the App Store review.
Attention! We strongly discourage the storage of personal user data! If you plan to pass this data, be sure to indicate this in the ‘Nutrition label’ when submitting the application to the App Store review.
Example:
Each devtodev project can have up to 30 custom user properties. User custom property values can be a number, a string (up to 500 symbols), or a boolean value.
This is how you can set properties on the current user profile:
To get the current value stored in the user profile on the SDK, you need to use the method:
getValue(key: String, _completionHandler: @escaping (Any) -> Void)
This is how you can set properties on the current user profile:
To get the current value stored in the user profile on the SDK, you need to use the method:
(void)getValueWithKey:(NSString * _Nonnull)key :(void (^ _Nonnull)(id _Nullable))completionHandler;
This is how you can set properties on the current user profile:
To get the current value stored in the user profile on the SDK, you need to use the method:
getValue(key: String, handler: (Any?) -> Unit)
This is how you can set properties on the current user profile:
To get the current value stored in the user profile on the SDK, you need to use the method:
getValue(key: String, handler: (Any?) -> Unit)
This is how you can set properties on the current user profile:
To get the current value stored in the user profile on the SDK, you need to use the method:
This is how you can set properties on the current user profile:
To get the current value stored in the user profile on the SDK, you need to use the method:
This is how you can set properties on the current user profile:
To get the current value stored in the user profile on the SDK, you need to use the method:
This is how you can set properties on the current user profile:
To get the current value stored in the user profile on the SDK, you need to use methods:
This is how you can set properties on the current user profile:
To get the current values stored in the user profile on the SDK, you need to use the methods:
TryGetBool(key: String, callback: Callable)
TryGetFloat(key: String, callback: Callable)
TryGetInt(key: String, callback: Callable)
TryGetString(key: String, callback: Callable
It removes a property or a list of properties and their values from the current user profile.
To remove all properties from the user card, use:
To track payments in a real currency, dispatch this event right after the system validates that the payment went through successfully. The event is fundamental and mandatory for all the app metrics related to monetization.
If you want to track non-basic events, you can create custom events of your own. How you are going to apply them, depends solely on you.
devtodev supports no more than 300 custom event names in a single project. Events that exceed the limit of custom event names will be discarded. Try to integrate the tracked actions by type to the event name level, and move the characteristic tags in the parameters.
For example, if you need to track purchasing “Paper” and “Pen” items, then you don’t need to create two events with the names “Paper Purchase” and “Pen Purchase”. Create a “Purchase” event and add an “Item” parameter to it with the appropriate “Paper” or “Pen” value. This way, you can use just one event to track many items.
For a string parameter, you can use no more than 50,000 unique values for the entire history of events. If the number of unique values exceeds the limit, the parameter gets locked by the system and gets discarded from the received data. Therefore, we don’t recommend using highly variable parameters like user IDs or time as string values (moreover, they are automatically added to the event).
We strongly recommend that you do not change the data type passed in the same parameter. If you change the data type in a parameter, it will be duplicated with the same name, which may cause issues while processing reports.
The described method is available beginning with version 2.1.0!
Tracking of subscriptions is now available for Apple App Store and Google Play only.
To track your income from subscriptions, you need to call the following method at the moment of the subscription purchase even if the user signed up for a trial subscription: func subscriptionPayment(transaction: SKPaymentTransaction, product: SKProduct).
For example:
Further user actions - renewal, unsubscription, etc. are tracked by using the data received from AppStore in the server-server format. You will need the corresponding setting for it.
Also, if you want to track changes in the status of the subscriptions purchased before devtodev SDK 2.0 integration, you need to transfer your history of previously purchased subscriptions to devtodev.
The SDK monitors the need for historical data to avoid sending out excessive queries to App Store. Use the DTDAnalytics.isRestoreTransactionHistoryRequired
method to check whether or not there is a need in sending out the information about the previously purchased subscriptions to devtodev. The method returns BOOL value.
An example of a purchase history query with verification of the need for it:
Use the DTDAnalytics.subscriptionHistory
method to transfer the list of previously purchased subscriptions received from App Store.
If your project accounts users by user ID (not by device ID) and the device is used by more than one user, you need to filter the transaction history so that it will contain only those transactions that belong to the active user. Otherwise, subscriptions of all device users will be attributed to the user who was the first to launch the app after the integration of subscription tracking.
To track your income from subscriptions, you need to call the following method at the moment of the subscription purchase even if the user signed up for a trial subscription: func subscriptionPayment(transaction: Transaction, product: Product).
For example:
Fork with Transaction.updates:
Further user actions - renewal, unsubscription, etc. are tracked by using the data received from AppStore in the server-server format. You will need the corresponding setting for it.
Also, if you want to track changes in the status of the subscriptions purchased before devtodev SDK 2.0 integration, you need to transfer your history of previously purchased subscriptions to devtodev.
The SDK monitors the need for historical data to avoid sending out excessive queries to App Store. Use the DTDAnalytics.isRestoreTransactionHistoryRequired
method to check whether or not there is a need in sending out the information about the previously purchased subscriptions to devtodev. The method returns BOOL value.
An example of a purchase history query with verification of the need for it:
Use the DTDAnalytics.subscriptionHistory
method to transfer the list of previously purchased subscriptions received from App Store.
If your project accounts users by user ID (not by device ID) and the device is used by more than one user, you need to filter the transaction history so that it will contain only those transactions that belong to the active user. Otherwise, subscriptions of all device users will be attributed to the user who was the first to launch the app after the integration of subscription tracking.
To track your income from subscriptions, you need to call the following method at the moment of the subscription purchase even if the user signed up for a trial subscription:
(void)subscriptionPaymentWithTransaction:(SKPaymentTransaction * _Nonnull)transaction product:(SKProduct * _Nonnull)product;
For example:
Further user actions - renewal, unsubscription, etc. are tracked by using the data received from AppStore in the server-server format. You will need the corresponding setting for it.
Also, if you want to track changes in the status of the subscriptions purchased before devtodev SDK 2.0 integration, you need to transfer your history of previously purchased subscriptions to devtodev.
The SDK monitors the need for historical data to avoid sending out excessive queries to App Store. Use the (void)isRestoreTransactionHistoryRequiredWithCompletionHandler:( void (^ _Nonnull)(BOOL))completionHandler;
method to check whether or not there is a need in sending out the information about the previously purchased subscriptions to devtodev. The method returns BOOL value.
An example of a purchase history query with verification of the need for it:
Use the (void)subscriptionHistoryWithTransactions:(NSArray<SKPaymentTransaction *> * _Nonnull)transactions;
method to transfer the list of previously purchased subscriptions received from App Store.
If your project accounts users by user ID (not by device ID) and the device is used by more than one user, you need to filter the transaction history so that it will contain only those transactions that belong to the active user. Otherwise, subscriptions of all device users will be attributed to the user who was the first to launch the app after the integration of subscription tracking.
Before sending a request for subscription from your app, during the creation of BillingFlowParams
, to the setObfuscatedAccountId
function of the BillingFlowParams.newBuilder()
object insert obfuscatedAccountId
obtained from DTDAnalytics.getObfuscatedAccountId
.
Attention! The obfuscated identifier is returned asynchronously, outside of the calling thread!
Example:
To track your subscriptions, add this event immediately after the platform confirms that the subscription was approved by the user.
Further user actions - renewal, unsubscription, etc. are tracked by using the data received from Google Play in the server-server format. You will need the corresponding setting for it.
The subscriptionHistory
method is used for matching users with subscribers who purchased their subscriptions before the SDK 2.0 integration. Otherwise, it will be impossible to establish the affiliation when it gets renewed or cancelled.
To get a list of active subscriptions call billingClient.queryPurchasesAsync
. After successfully receiving a response from Google Play Services, pass it to DTDAnalytics.subscriptionHistory(purchaseList: List<String>).
purchaseList: List<String> purchaseList
- a string containing list of json objects is passed to the DTDAnalytics.subscriptionHistory
method. For the event to run, the json object must contain the following keys:
orderID
- a unique transaction identifier
productID
- a unique product identifier
The SDK monitors the need for historical data to avoid sending out excessive queries. Use the DTDAnalytics.isRestoreTransactionHistoryRequired
method to check whether or not there is a need in sending out the information about the previously purchased subscriptions to devtodev. The method returns a Boolean value.
Attention! DTDAnalytics.isRestoreTransactionHistoryRequired
is returned asynchronously, outside of the calling thread!
Example:
If your project accounts users by user ID (not by device ID) and the device is used by more than one user, you need to filter the transaction history so that it will contain only those transactions that belong to the active user. Otherwise, subscriptions of all device users will be attributed to the user who was the first to launch the app after the integration of subscription tracking.
Before sending a request for subscription from your app, during the creation of BillingFlowParams
, to the setObfuscatedAccountId
function of the BillingFlowParams.newBuilder()
object insert obfuscatedAccountId
obtained from DTDAnalytics.INSTANCE.getObfuscatedAccountId.
Attention! The obfuscated identifier is returned asynchronously, outside of the calling thread!
Example:
To track your subscriptions, add this event immediately after the platform confirms that the subscription was approved by the user.
Further user actions - renewal, unsubscription, etc. are tracked by using the data received from Google Play in the server-server format. You will need the corresponding setting for it.
The subscriptionHistory
method is used for matching users with subscribers who purchased their subscriptions before the SDK 2.0 integration. Otherwise, it will be impossible to establish the affiliation when it gets renewed or cancelled.
To get a list of active subscriptions call billingClient.queryPurchasesAsync
. After successfully receiving a response from Google Play Services, pass it to DTDAnalytics.subscriptionHistory(purchaseList: List<String>).
purchaseList: List<String> purchaseList
- a string containing list of json objects is passed to the DTDAnalytics.INSTANCE.subscriptionHistory
method. For the event to run, the json object must contain the following keys:
orderID
- a unique transaction identifier
productID
- a unique product identifier
The SDK monitors the need for historical data to avoid sending out excessive queries. Use the DTDAnalytics.INSTANCE.isRestoreTransactionHistoryRequired
method to check whether or not there is a need in sending out the information about the previously purchased subscriptions to devtodev. The method returns a Boolean value.
Attention! DTDAnalytics.INSTANCE.isRestoreTransactionHistoryRequired
is returned asynchronously, outside of the calling thread!
Example:
If your project accounts users by user ID (not by device ID) and the device is used by more than one user, you need to filter the transaction history so that it will contain only those transactions that belong to the active user. Otherwise, subscriptions of all device users will be attributed to the user who was the first to launch the app after the integration of subscription tracking.
In order to work with Unity subscriptions, you need to integrate the subscription module to your project. You can do it by manually importing the unitypackage.
Import DTDAnalytics.unitypackage to your project
Import DTDSubscriptions.unitypackage to your project.
For the DTDSubscriptions
module to function you need the DTDAnalytics
and Unity IAP modules.
You also need to create an AppleTangle
file. Open the Unity editor menu and choose Window → Unity IAP → Receipt Validation Obfuscator (pic. 1).
In case you don’t use the IAP receipt validation, clear the input field under “2. Paste the key here:” and click Obfuscate Google Play Licence Key (pic. 2).
Restore purchase history in order for the module to function correctly.
If you use Google Play, after successful IAP initialization call the DTDSubscriptions.History()
method.
Example:
Example:
Add a DTDSubscriptions.Payment(Product product)
call to the ProcessPurchase
method.
Below you can see an example of the entire script:
The event allows you to track tutorial completion and identify the stages where you lose new users.
We recommend tracking the starting point (value -1) before beginning the first tutorial stage, then passing the counting number of every completed stage after its completion (integers larger than 0), and at the end, marking the moment of the last tutorial stage completion (value -2).
If your app has an option of skipping the tutorial and the user has used it, then it’s necessary to send a refusal value (value 0) only.
The method takes on the step value with an integer type.
The method takes on the step value with an integer type.
The method takes on the step value with an integer type.
The method takes on the step value with an integer type.
The method takes on the step value with an integer type.
The method takes on the step value with an int base type.
The method takes on the step value with an integer type.
The method takes on the step value with an int32 base type.
The method takes on the step value with an integer type.
The event should be dispatched right after the level-up. The number of the level reached is passed to the level
parameter.
To monitor the average account balance of in-game currency by the end of each level, dispatch in-game currencies (resources) names and their amounts to the method signature:
Attention! The number of tracked in-game currencies or resources (their unique names) should not exceed 30 at all times.
The event should be dispatched right after the level-up. The number of the level reached is passed to the level
parameter.
To monitor the average account balance of in-game currency by the end of each level, dispatch in-game currencies (resources) names and their amounts to the method signature:
Attention! The number of tracked in-game currencies or resources (their unique names) should not exceed 30 at all times.
The event should be dispatched right after the level-up. The number of the level reached is passed to the level
parameter.
To monitor the average account balance of in-game currency by the end of each level, dispatch in-game currencies (resources) names and their amounts to the method signature:
Attention! The number of tracked in-game currencies or resources (their unique names) should not exceed 30 at all times.
The event should be dispatched right after the level-up. The number of the level reached is passed to the level
parameter.
To monitor the average account balance of in-game currency by the end of each level, dispatch in-game currencies (resources) names and their amounts to the method signature:
Attention! The number of tracked in-game currencies or resources (their unique names) should not exceed 30 at all times.
The event should be dispatched right after the level-up. The number of the level reached is passed to the level
parameter.
To monitor the average account balance of in-game currency by the end of each level, dispatch in-game currencies (resources) names and their amounts to the method signature:
Attention! The number of tracked in-game currencies or resources (their unique names) should not exceed 30 at all times.
The event should be dispatched right after the level-up. The number of the level reached is passed to the level
parameter.
To monitor the average account balance of in-game currency by the end of each level, dispatch in-game currencies (resources) names and their amounts to the method signature:
Attention! The number of tracked in-game currencies or resources (their unique names) should not exceed 30 at all times.
The event should be dispatched right after the level-up. The number of the level reached is passed to the level
parameter.
You can send and track the following data along with the level values: an average amount of the in-game currency by the end of the level, user spendings on the level, and amounts of purchased or earned in-game currency/resources. Unfortunately, Web SDK doesn’t allow to automatically calculate spending and receiving of the in-game currency/resources while users are passing the level (data accumulation on the Web might be inaccurate as users might utilize multiple browsers and devices, as well as erase local browser data).
Attention! The number of tracked in-game currencies or resources (their unique names) should not exceed 30 at all times.
The event should be dispatched right after the level-up. The number of the level reached is passed to the level
parameter.
To monitor the average account balance of in-game currency by the end of each level, dispatch in-game currencies (resources) names and their amounts to the method signature:
Attention! The number of tracked in-game currencies or resources (their unique names) should not exceed 30 at all times.
The event should be dispatched right after the level-up. The number of the level reached is passed to the level
parameter.
To monitor the average account balance of in-game currency by the end of each level, dispatch in-game currencies (resources) names and their amounts to the method signature:
Attention! The number of tracked in-game currencies or resources (their unique names) should not exceed 30 at all times.
To track the average balance of in-game currency disregarding the level up event, pass the list of in-game currency (resource) names and their amount to the method signature:
You need to dispatch the event after every game account balance refill if you want to track the average in-game currency amount acquired or earned by the players for a certain timeframe or during a level playthrough.
acrualType
can receive one of the following values:
acrualType
can receive one of the following values:
accrualType
can receive one of the following values:
accrualType
can receive one of the following values:
AccrualType
can receive one of the following values:
AccrualType
can receive one of the following values:
Example:
acrualType
can receive one of the following values:
Pass this event after every purchase if you want to track in-game currency spends and items’ popularity. You can apply this event to both games and any apps with virtual currency.
In case the item is sold for more than one currency/resource, you need to build a dictionary with all the names and amounts of the currencies/resources.
In case the item is sold for more than one currency/resource, you need to build a dictionary with all the names and amounts of the currencies/resources.
In case the item is sold for more than one currency/resource, you need to build a dictionary with all the names and amounts of the currencies/resources.
In case the item is sold for more than one currency/resource, you need to build a dictionary with all the names and amounts of the currencies/resources.