This document explains how to download, setup and use Unity SDK for Countly. You can download latest release from Github.
Following are some of the key assumptions being considered while developing the SDK. Please take into account following considerations before integrating this SDK:
- This SDK is developed in Unity 2018 2.7f1
- Scripting version is based on .NET 4.x equivalent
- API Compatibility Level is based on .NET 4.x
Integration
- Clone/download the source code from github- https://github.com/Countly/countly-sdk-unity
- Unzip the package (if you have downloaded ZIP file).
- Look for a folder named “Assets”. Copy all the contents of “Assets” folder and paste it inside your app’s Assets folder. Unity will import the new assets now.
- Now, update the following player settings: a. Package Name: App's Bundle ID b. Scripting Runtime Version: .NET 4x Equivalent
- Create an account on Firebase (firebase.google.com). Go to Firebase Console (https://console.firebase.google.com/). Create a new project.
- Add your app (Android/iOS) to the project created in Step 4. Specify the same package name that you specified in Unity Editor for your app.
- Register your app and download
google-services.json
for Android orGoogleService-Info.plist
for iOS file, at Step 2 of the registration process. We do not need to proceed after step 2. So, leave the further steps. - Place the file downloaded under your app's
Assets
folder. - Run
Android Resolver
in case of Android fromAssets
>Play Service Resolver
>Android Resolver
=>Resolve
. For iOS we don’t need to do anything. - Attach
AppInitScript.cs
file to the main scene of your Unity application.
Note that a script named “Testing.cs” under folder “Assets\Scripts\Main\Testing” contains examples to test all the features of the SDK. You can take reference from this script to know how to utilize each feature of the SDK.
Initializing the SDK
To initialize Countly Unity SDK, use following two methods with appropriate parameters. Note that the following two methods should be added inside your application start event, in the exact order with method Begin
being called before method SetDefaults
.
Begin method
Countly.Begin(string serverUrl, string appKey, string deviceId = null);
serverUrl: Required Type: string Description: The URL of the Countly Server where you are going to post our requests. Example: https://us-try.count.ly/
appKey: Required Type: string Description: The “App Key” for the app that you created on Countly Server. Example: 124qw3er5u678qwef88d6123456789qwertyui123
deviceId: Optional Type: string Description: Your Device ID. It is an optional parameter. Example: f16e5af2-8a2a-4f37-965d-qwer5678ui98
If you do not provide device ID during initialization, SDK will generate a Device ID on its own and use this Device ID for all future requests made to the Countly server. This Device ID is persisted by the SDK per device.
If you provide a device ID to the SDK and later you are initializing the SDK again with a different device ID, the old Device ID will be used by the SDK and not the new one because the priority is as follows:
Cached Device ID > Provided Device ID Upon Initialization > SDK Generated Device ID
Which server/host name should I use inside SDK?
If you are using Countly Enterprise trial servers, use corresponding server name, e.g., https://try.count.ly, https://us-try.count.ly or https://asia-try.count.ly
If you use Countly Lite and Countly Enterprise, use your own domain name.
SetDefaults
This method takes as input an instance of CountlyConfigModel
class. The constructor for CountlyConfig
model takes following list of parameters (the default values are mentioned alongside each one of them):
- string salt = NULL
- bool enablePost = false
- bool enableConsoleErrorLogging = false
- bool ignoreSessionCooldown = false
- bool enableManualSessionHandling = false
- int sessionDuration = 60
- int eventThreshold = 100
- int storedRequestLimit = 1000
- int totalBreadcrumbsAllowed = 100
- TestMode? notificationMode = NULL
- bool enableAutomaticCrashReporting = true
Below you can find details of each method.
salt: Used to prevent parameter tampering. Type: string
enablePost: When set to true, all requests made to the Countly Server will be done using HTTP POST. Otherwise, SDK sends all requests using HTTP GET method. In some cases, if the data to be sent exceeds 1800 characters limit, the SDK uses POST method. Type: bool
enableConsoleErrorLogging: This parameter is only useful when you are debugging your application in Unity Editor. When set to true, it basically turns on Error Logging on Unity Console window Type: bool
ignoreSessionCooldown: To turn on/off session cooldown behavior as mentioned in the development-guide Type: bool
enableManualSessionHandling: To turn on/off manual session handling in the application. Type: bool
sessionDuration: To set the interval (in seconds) after which the application will automatically extend the session provided manual session is disabled. This interval is also used to process requests in queue. The default value is 60 (seconds). Type: bool
eventThreshold: To set a threshold value that limits the number of events that can be recorded internally by the system before they all can be sent together in one request. Once the threshold limit is reached, the system groups all recorded events and send them to the server. The default value is 100 (events). Type: int
totalBreadcrumbsAllowed: To set a threshold value that limits the number of requests that can be stored internally by the system. The system processes these requests after every sessionDuration interval has passed. The default value is 1000 (requests). Type: int
notificationMode (Optional): When null, SDK disables Push Notification for the device. Otherwise, when provided an appropriate value from the enum TestMode, SDK uses the supplied mode for sending Push Notifications. Type: Enum of type TestMode
enableAutomaticCrashReporting (Optional): This is used to turn on/off automatic crash reporting. When set to true, SDK will catch exceptions and automatically report them to the Countly server, otherwise not. Type: bool
var configObj = new CountlyConfigModel(null, false, false, false, false, 60, 100, 1000, 100, TestMode.TestToken, false);
await Countly.SetDefaults(configObj);
Session handling
Unity SDK can handle sessions in two ways: Automatic session handling and manual session handling. If you are in doubt, use automatic session handling.
Automatic Session Handling
Begin Session: SDK is responsible for automatically handling Countly session in your app. As soon as you call the initialization methods (Begin and SetDefaults) in your app start event, SDK will start the session automatically (only when you set enableManualSessionHandling
to true during initialization).
Update Session: SDK is responsible for automatically extending the session after every 60 seconds (default value). This value is configurable during initialization using parameter sessionDuration. It cannot be modified any time after initialization.
Note that in iOS, session will not extend when the app is in background. As soon as user switches back to the app, session extension will resume. In Android, session will extend on both occasions: foreground and background.
End Session: SDK is responsible for automatically ending the session whenever user quits the application.
Session will be ended automatically when user calls Application.Quit() method available in Unity.
Manual Session Handling
This is used when you want to start a session on your app manually.
Begin Session: Starts the session manually. You need to call the following method:
Countly.BeginSessionAsync();
Update Session: Extends the session manually. You need to call following method:
Countly.ExtendSessionAsync();
End Session: Ends the session manually. You need to call the following method:
Countly.EndSessionAsync()
Optional parameters
Countly servers recognize the location of the user’s device from their IP address. However, you can also specify user’s location manually using the following methods.
Note: You need to use the following methods in conjunction to specify the exact location manually. Also, IP address can be left out intentionally when you want to specify a location but don’t have access to user’s IP address. This is because Countly server gives priority to IP address. So, if you’ve specified country, city and coordinates of a different location and IP address of a different location, Countly server will choose the location from the IP address.
Setting country code
In order set the country, you need to call method SetCountryCode
.
Syntax: Countly.SetCountryCode(string country_code);
country_code (required) Type: string Desc: It takes an ISO Country Code in string format, as parameter. Ex: Countly.SetCountryCode(“au”);
Setting city
In order to set the city, you need to call method SetCity.
Syntax: Countly.SetCity(string cityname);
cityname (required) Type: string Desc: It takes name of the city in string format, as parameter. Ex: Countly.SetCity(“Berlin”);
Setting location
In order to set the coordinates, you need to use method SetLocation
. Syntax: SetLocation(double latitude, double longitude);
There are two parameters, latitude and longitude:
latitude and longitude (required) Type: double Ex: Countly.SetLocation(34.9285,138.6007);
Setting IP address
You can choose to set (overwrite) the IP address of the user’s device. In order to set the IP Address, you need to first get user’s device IP Address and then use method SetIPAddress
.
Syntax: Countly.SetIPAddress(string ip_address);
ip_address (required) Type: string Desc: It takes IP address of the user’s device. Ex: Countly.SetIPAddress(“SOME_IP_ADDRESS”);
Disabling location
This will completely remove and disable everything that has been previously set in context of location like country, city, location and IP address.
Parameter(s): None Ex: `Countly.DisableLocation();``
Events
Unity SDK allows you to report custom events. An event can be anything which is a user action, e.g button click, hover, purchases or level passing information. You can report any type of events to the Countly server.
Unity SDK helps record as many events as you can (you can set a threshold limit during initialization), and the system will send them automatically to the server once the threshold limit is reached. By default, Countly tracks only up to 500 events, however this is also configurable.
Note: You need to first set the threshold value that decides the number of events that can be recorded by the system, i.e., EventSendThreshold
value, during initialization. The default value is 100. Once SDK records this much events, SDK will send all collected events at once in a single request.
Below you can find methods for sending custom events.
Recording an event: You can record an event by providing the event name. The event will not be reported to the Countly server immediately and will be reported to the server once the threshold limit is reached.
Syntax: Countly.RecordEventAsync(string key);
key: required Type: string Desc: The name of the event. Example: Countly.RecordEventAsync(“Game_Level_X_Started”);
Recording an event (overload): This is an overload to the method we defined above. We can provide other information related to the particular event with this overload method.
Syntax: Countly.RecordEventAsync(string key, IDictionary<string, object> segmentation,
int? count = 1, double? sum = 0, double? duration = null)
Parameter(s):
key (required) Type: string Desc: The name of the event.
segmentation (optional) Type: IDictionary<string, object> Desc: Payload data to be sent along with the event
count (optional) Type: integer Desc: Default value is 1
sum (optional) Type: double Duration: Optional Type: double
Example:
Countly.RecordEventAsync("Game_Level_X_Started",
new Dictionary<string, object>
{
{ "Time Spent", "1234455"},
{ "Retry Attempts", "10"}
});
Crash Reporting
Unity SDK has the option to send crash reports to your Countly service. This can be done in two ways, automatic and manual.
Automatic crash reporting
Countly Unity SDK automatically reports uncaught exceptions/crashes, in the application, to the Countly server.
Manual Crash Reporting
Apart from automatically reporting crashes/uncaught exceptions to the Countly server, the SDK allows you to report your custom errors by using method SendCrashReportAsync
.
Syntax:
Countly.SendCrashReportAsync(string message, string stackTrace, LogType type, IDictionary<string, object> segments = null)
Parameters:
message (required) Type: string Desc: Complete error message.
stackTrace (required) Type: string Desc: Complete stack trace of the exception.
type (required) Type: A value of enum LogType, defined under UnityEngine namespace. Desc: You can choose from the various values defined in the enum LogType.
segments (optional) Type: IDictionary<string, object> Desc: Custom data in key-value pairs of string and object. This data will be posted to the Countly server along with the exception details.
Using breadcrumbs
Additionally, SDK allows you to leave breadcrumbs that would be submitted together with the crash reports. These breadcrumbs are added automatically and sent along with the crash report (for both automatically caught and manually caught exceptions).
You can add breadcrumbs in the SDK using method AddBreadcrumbs
. A breadcrumb is a string with at most 1000 character and this cannot be modified. We can add a maximum of 100 breadcrumbs (as it is default value) in the system. However, we can modify this during initialization with parameter totalBreadcrumbsAllowed
.
Syntax: Countly.AddBreadcrumbs(string breadcrumb);
Parameter(s): breadcrumb: A string value Type: String
Setting up views
Manual View (Screen) Tracking
Countly Unity SDK supports manual view (screen) tracking. With this feature, you can report what views a user did, and for how long. Thus, whenever there is a screen switch in your app, you can report it to Countly server by using following method:
Syntax: `Countly.ReportViewAsync(string name, bool hasSessionBegunWithView = false);``
Parameter(s):
name (required) Type: string Desc: The name of the view to be reported.
hasSessionBegunWithView (optional) Type: bool Desc: Set it to true to indicate that the session started with this view
Ex: Countly.ReportViewAsync(“LoginScreen”);
View Actions
Additionally, it is possible to report actions taken on views to display on heat maps or any other purpose. For that, you need to use method ReportActionAsync.
Syntax: Countly.ReportActionAsync(string type, int x, int y, int width, int height);
Parameter(s):
type: action type, as click, touch, longpress, etc x: x coordinate of action y: y coordinate of action width: width of the screen height: height of the screen
Ex: Countly.ReportActionAsync("Touch", 0, 0, 50, 50);
Star rating
When a user rates your application, you can report it to the Countly server using method ReportStarRatingAsync
. For this, you can optionally set Countly Unity SDK to automatically ask users for a 1-to-5 star-rating, depending on app launch count for each version.
Syntax: Countly.ReportStarRatingAsync(string platform, string app_version, int rating);
Parameter(s):
platform: platform on which application runs app_version: application's version number rating: user's 1-to-5 rating
Ex: Countly.ReportStarRatingAsync("android", "0.1", 3);
User Profiles
Countly Unity SDK allows you to upload specific data related to a user to Countly server. SDK allows you to set following predefined data for a particular user:
- Name: Full name of the user
- Username: Username of the user
- Email: Email address of the user
- Organization: Organization the user is working in
- Phone: Phone number
- Picture Url: Web based Url for user’s profile
- Gender: Gender of the user (use only single char like ‘M’ for Male and ‘F’ for Female)
- Birth year: Birth year of the user
Apart from the above data, you can also add your own custom data for a user. SDK allows you to upload user details using following methods. You may choose one of the following methods as per your requirement.
Setting user details
You can set all the details (specified above) of a user along with some custom data using method SetUserDetailsAsync
.
Syntax: SetUserDetailsAsync();
Parameter(s): None This method is an instance method and not a static method. It doesn’t take any parameters. You first need to create an instance of class CountlyUserDetailsModel
. The constructor for this class takes following number of parameters:
- Name: String
- Username: String
- Email: String
- Organization: String
- Phone: String
- Gender: String
- Birth year: String
- Custom: String. It is a json string containing key-value pairs. It is used to send custom data.
Example:
var userDetails = new CountlyUserDetailsModel(
"Full Name", "username", "useremail@email.com", "Organization",
"222-222-222",
"http://webresizer.com/images2/bird1_after.jpg",
"M", "1986",
new Dictionary<string, object>
{
{ "Hair", "Black" },
{ "Race", "Asian" },
});
await userDetails.SetUserDetailsAsync();
Setting custom user details
SDK allows you the flexibility to send only custom data to Countly servers when you don’t want to send other user related data. Similar to the above method, it is also an instance method and not a static method. So, you first need to create an instance of class CountlyUserDetailsModel
. All the parameters expected in the constructor remain the same. You can leave all parameters as NULL and just provide the custom data segment for sending custom data to the Countly server.
Syntax: SetCustomUserDetailsAsync();
Parameter(s): None
var userDetails = new CountlyUserDetailsModel(
new Dictionary<string, object>
{
{ "Nationality", "Indian" },
{ "Height", "5.8" },
{ "Mole", "Lower Left Cheek" }
});
await userDetails.SetCustomUserDetailsAsync();
Modifying Custom Data Properties
Apart from setting user details (SetUserDetailsAsync
) and custom user details (SetCustomUserDetailsAsync
), SDK allows you to set/modify specific custom data properties. The system records multiple properties at once and reports them (updates to the server) when you want.
Below are some of the methods available in the SDK. All these methods are static methods and defined in the class CountlyUserDetailsModel
.
Set: Sets a value to the provided key. Syntax: CountlyUserDetailsModel.SetOnce(string key, string value);
Parameter(s): key: Name of the property to be updated value: Value to be updated with
Example: CountlyUserDetailsModel.Set("Weight", "80");
CountlyUserDetailsModel.Save();
SetOnce: Sets value to key, only if property was not defined before for this user Syntax: CountlyUserDetailsModel.SetOnce(string key, string value);
Parameter(s): Already defined above.
Example: CountlyUserDetailsModel.SetOnce("Weight", "90");
CountlyUserDetailsModel.Save();
In the above example, Weight will not be updated with value “90” if you’ve already updated Weight with a certain value.
Increment: To increment value on server by 1 (if no value on server, assumes it is 0)
Syntax: CountlyUserDetailsModel.Increment(string key);
Parameter(s): Already defined above.
Example: CountlyUserDetailsModel.Increment("Weight");
CountlyUserDetailsModel.Save();
Increment By: To increment value on server by provided value (if no value on server, assumes it is 0)
Syntax: CountlyUserDetailsModel.IncrementBy(string key, double value);
Parameter(s): Already defined above.
Ex: CountlyUserDetailsModel.IncrementBy("Weight", 1);
CountlyUserDetailsModel.Save();
Multiply: To multiply value on server by provided value (if no value on server, assumes it is 0)
Syntax: CountlyUserDetailsModel.Multiply(string key, double value);
Parameter(s): Already defined above.
Ex: CountlyUserDetailsModel.Multiply("Weight", 2);
CountlyUserDetailsModel.Save();
Max: To store maximal value from the one on server and provided value (if no value on server, uses provided value)
Syntax: CountlyUserDetailsModel.Max(string key, double value);
Parameter(s): Already defined above.
Ex: CountlyUserDetailsModel.Max("Weight", 90);
CountlyUserDetailsModel.Save();
Min: To store minimal value from the one on server and provided value (if no value on server, uses provided value).
Syntax: CountlyUserDetailsModel.Min(string key, double value);
Parameter(s): Already defined above.
Ex: CountlyUserDetailsModel.Min("Weight", 40);
CountlyUserDetailsModel.Save();
Push: Add one or many values to array property (can have multiple same values, if property is not array, converts it to array).
Syntax: CountlyUserDetailsModel.Push(string key, string[] value);
Parameter(s): value: A string array containing list of values that you want to set for the provided key.
Ex: CountlyUserDetailsModel.Push("Mole", new string[] { "Left Cheek", "Back", "Toe" });
CountlyUserDetailsModel.Save();
Push Unique: Add one or many values to array property (will only store unique values in array, if property is not array, converts it to array).
Syntax: CountlyUserDetailsModel.PushUnique(string key, string[] value);
Parameter(s): Already defined above.
Ex: CountlyUserDetailsModel.PushUnique("Mole", new string[] { "Right Leg", "Right Leg" });
CountlyUserDetailsModel.Save();
Pull: Remove one or many values from array property (only removes value from array properties)
Syntax: CountlyUserDetailsModel.Pull(string key, string[] value);
Parameter(s): Already defined above.
Ex: CountlyUserDetailsModel.Pull("Mole", new string[] { "Right Leg", "Back" });
CountlyUserDetailsModel.Save();
Recording multiple update requests
Apart from updating a single property in one request, you can modify multiple (unique) properties in one single request. This way, you can increment Weight and multiply Height in the same request. Similarly, you can record N number of modify requests and Save them all together in one single request instead of multiple requests.
In order record a “modify custom user detail” request, you just need to call the particular methods but DO NOT call “Save” method immediately after each method. CountlyUserDetailsModel.Save()
method immediately posts all modify requests recorded yet.
Note that if you are going to modify multiple properties in one request, make sure you properties are unique, i.e., a property shouldn’t be modified more than once in a single request. However, if you record a property more than once, only the latest modifier will be posted to the server.
Example:
CountlyUserDetailsModel.Max("Weight", 190);
CountlyUserDetailsModel.Multiply("Weight", 190);
CountlyUserDetailsModel.Min("Height", 5.5);
CountlyUserDetailsModel.Push("Mole", new string[] { "Left Cheek", "Back", "Toe" });
CountlyUserDetailsModel.Save();
You can record N number of modify requests and call “Save” when you want to post all events recorded before calling “Save” method.
Note: In the above example, you can see Max and Multiply are modifying the same property “Weight”. Therefore in such a scenario, only Multiply request will pushed to the server and Max request will not.
Push Notifications
This section requires setting up either APNS (Apple Push Notification Services) or FCM (Firebase Cloud Services). For APNS, you need to get push credentials and upload to Countly. This document explains how to retrieve and upload push credentials for APNS. If you are developing for Android, please read this documentation and follow instructions to setup for GCM/FCM.
After setting up push notification credentials, you must initialize Push Notification for Countly Unity SDK. However, SDK already does it for you so, you don’t have to initialize it separately. At the beginning of this documentation, go to “initialization” process (method SetDefaults) where we init the Countly Unity SDK. In that method, you can see we have a parameter (last one) named TEST_MODE.
- If you don’t want to enable Push Notification for your application, you can pass NULL to this parameter during initialization.
- If you want to enable Push Notification for your application, you can provide any of the suitable value from the enum TestMode under namespace Assets.Scripts.Enums.
So, the SDK already initializes Push Notification for you. But, if you’ve disabled Push Notification during initialization and you want to enable anytime after that, you can do that by using following method EnablePush.
Syntax: Countly.EnablePush(TestMode mode);
Parameter(s): Explained above.
Key Points:
- Push Notification with banner image in the background is only supported for Android platform. Banner image is not supported on iOS platform.
- Push Notifications will only appear when the app is in Foreground. As soon as user switches to another application and your app is in background, your session will end and you’ll have to initialize Push Notification again on your AppStart or OnFocus event, if you haven’t initialized it in the SetDefaults method of the SDK by passing TestMode parameter.
- For platforms Android and iOS, the notification icon can be set as follows: For Android, place the notification icons under folder “Assets\Plugins\Android\res” for different screen densities. The name of the icon must be “notification_icon”. A sample PNG file is placed under the folder “drawable”. For iOS, iOS platform will basically pick your app icon as the default push notification icon. So, you don’t need to do anything for iOS platform.
Changing Device ID
Countly Unity SDK persists Device ID which you provide during initialization or generates a random ID, if you don’t provide it. This Device ID will be used persistently for all future requests made from a device until you change that.
The SDK allows you to change the Device ID at any point of time. You can use following any of the following two methods for changing Device ID, depending upon your scenario.
Change device ID & end current session:
This method changes the Device ID and does following other operations:
- Ends all the events that have been recorded till now.
- Ends current session.
- Updates Device ID and starts new session with new Device ID.
Syntax: Countly.ChangeDeviceIDAndEndCurrentSessionAsync(string deviceId);
Parameter(s): deviceId: Required Type: string Desc:** The new device id
Ex: Countly.ChangeDeviceIDAndEndCurrentSessionAsync(“NEW_DEVICE_ID”);
Change Device ID And Merge Session Data
This method changes the Device ID and merges data for both Device IDs on the Countly server.
Syntax: Countly.ChangeDeviceIDAndMergeSessionDataAsync(string deviceId);
Parameter(s): Explained above. Ex: Countly.ChangeDeviceIDAndMergeSessionDataAsync(“NEW_DEVICE_ID”);