This document includes necessary information for integrating Countly iOS SDK in your Xamarin.iOS project.

Minimum iOS version

Countly iOS SDK needs a minimum of iOS 8.0 ( macOS 10.9) ,and requires Xcode 9.0+ with Base SDK iOS 10.0+ to work.


To integrate CountlySdk into your application, please follow these steps:

  • Start Xamarin Studio.
  • From the File menu, select New > Solution
  • Add a new Xamarin.iOS project called CountlyTestNative to the solution,
  • Install Countly Analytics for Xamarin (iOS) package from Nuget using command Install-Package CountlySDK.Xamarin.iOS into your project.
  • In your Appdelegate, add using CountlySdk and inside FinishedLaunching add following lines at the beginning
using CountlySdk;

namespace CountlyTestNative.iOS
    public class AppDelegate : UIApplicationDelegate
             public override bool FinishedLaunching(UIApplication application,                NSDictionary launchOptions)
            CountlyConfig config = new CountlyConfig();
            config.AppKey = "your_App_Key";
            config.Host = "https://YOUR_COUNTLY_SERVER";
            return true;
  • You need to set your app key and host on CountlyConfig object. Make sure you use App Key (found under Management > Applications) .

If you are using Countly Enterprise trial servers host should be https://try.count.ly

In iOS 13 a new SceneSession Lifecycle is added, which causes some issues in Countly Sessions logging, here are some steps required to fix this issue:
1. Delete the "Application Scene Manifest" entry from the app's Info.plist
2. Comment or delete these methods in AppDelegate.cs:

public UISceneConfiguration GetConfiguration(UIApplication application, UISceneSession connectingSceneSession, UISceneConnectionOptions options)
public void DidDiscardSceneSessions(UIApplication application, NSSet<UISceneSession> sceneSessions)
  • You can run your project and see first session data immediately on your Dashboard.

Advanced Configuration

Debug Mode

If you want to enable debug mode of Countly iOS SDK which output internal infos, errors and warnings into console, you can set enableDebug flag on CountlyConfig object before starting Countly.

config.EnableDebug = true;

Additional Features

If you want to use additional features like PushNotifications, CrashReporting and AutoViewTracking you can specify them in features array on CountlyConfig object before you start:

    public class AppDelegate : UIApplicationDelegate
             public override bool FinishedLaunching(UIApplication application,                NSDictionary launchOptions)      
            CountlyConfig config = new CountlyConfig();
            config.AppKey = "your_App_Key";
            config.Host = "https://YOUR_COUNTLY_SERVER";
            config.Features = new NSObject[] {        Constants.CLYPushNotifications,                         Constants.CLYCrashReporting, Constants.CLYAutoViewTracking };
            return true;

Device ID

  • Custom Device ID

If you want to use custom device ID, you can set deviceID property on CountlyConfig object.

config.DeviceID = "customDeviceID";

Note: Once set, device ID will be stored persistently in device on the first launch, and will not change even after app delete and re-install, unless you change it explicitly.

  • Changing Device ID

You can use SetNewDeviceID method to change device id on runtime after you start Countly. If onServer bool is set to true, old device ID on server will be replaced with the new one, and data associated with old device ID will be merged automatically.


Otherwise, if onServer bool is not set, device will be counted as a new device on server.

  • Handling User Login and Logout

If your app allows users to login, then logged in users can be tracked with custom user ID. For this , you can use UserLoggedIn() and UserLoggedOut() methods for changing device ID.

UserLoggedIn() method handles switching from device ID to custom user ID for logged in users.


UserLoggedOut() method handles switching from custom user ID to device ID for logged out users. It is a method that handles resetting device ID to default one and starting a new session.


Forcing Device ID Initialization

On the first app launch, Countly iOS SDK initializes device ID as specified in CountlyConfig object deviceID property, and stores it persistently. After this point, even if you delete and re-install the app Countly iOS SDK will continue to use initially stored device ID, to track app re-installs. So, while developing if you set deviceID property to something else on consecutive app launches, it will have no effect. In this case, you can set ForceDeviceIDInitialization flag on CountlyConfig object, to force device ID initialization again. This will reset the initially stored device ID and Countly iOS SDK will work as if it is the first app launch.

			config.ForceDeviceIDInitialization = true;

After you start Countly with ForceDeviceIDInitialization flag only once while developing, you can remove that line. ForceDeviceIDInitialization flag is not meant for production, it is only for debugging purposes while developing.

Other Settings

On CountlyConfig object you can specify further optional settings such as:

  • Update Session Period

You can specify UpdateSessionPeriod on CountlyConfig object before starting Countly. It is used for session updating and sending events to server periodically. It’s default falue is 60 seconds for iOS.

config.UpdateSessionPeriod = 80;
  • Manual Session Handling

you can set ManualSessionHandling flag on CountlyConfig object to handle sessions manually.

config.ManualSessionHandling = true;

Countly SDK for Xamarin tracks sessions automatically and sends begin_session request on initialization, periodical update session request on specified interval (60 sec by default), end_session request when app goes to background, and begin_session request again when app comes back to foreground.

If ManualSessionHandling flag is set, Countly iOS SDK does not send these requests automatically. So, you need to call beginSession, updateSession and endSession methods manually after you start Countly, depending on your own definition of a session.

  • Event Send Threshold

EventSendThreshold is used to send events requests to server when number of recorded events reach it without waiting for next update session request.

 config.EventSendThreshold = 5;
  • Stored Requests Limit

StoredRequestsLimit is used to limit number of request to be queued. In case your Countly server is down, queued request may reach excessive numbers, and it may cause problems with being delivered to server and stored on the device. To prevent this, Countly SDK will only store requests up to limit value. By default this is 1000.

 config.StoredRequestsLimit = 5000;
  • Always use POST method

You can set AlwaysUsePOST flag on CountlyConfig object before starting Countly. It is used for sending all requests using HTTP POST method regardless of the data size. If set, all requests will be sent using HTTP POST method. Otherwise; only the requests with a file upload or data size more than 2048 bytes will be sent using HTTP POST method.

config.AlwaysUsePOST = true;
  • Additional Info

  • Custom Header Field

You can set optional customHeaderFieldName to be sent with every request. It is useful if your server requires special headers to be sent for security reasons. Every request sent to Countly server will have this custom HTTP header and its value will be what is specified in customHeaderFieldValue property.

config.CustomHeaderFieldName = "X-My-Custom-Field";
config.CustomHeaderFieldValue = "my_custom_value";


You can set EnableAttribution flag on CountlyConfig object to enable campaign attribution. If set, IDFA (Identifier For Advertising) will be sent with every begin_session request, unless user has limited ad tracking in iOS Settings.

config.EnableAttribution = true;

Zero-IDFA Fix

With the release of iOS10, IDFA (Identifier for Advertising) value is 00000000–0000–0000–0000–000000000000 for all users who switched Limit Ad Tracking setting on. If you are currently using a Countly iOS SDK version older than v16.06.4 and upgrading; you may need to apply Zero-IDFA fix for persistently stored device ID and queued requests. To apply fix, you need to set ApplyZeroIDFAFix flag on CountlyConfig object:

config.ApplyZeroIDFAFix = true;
  • Star Rating

You can set Countly iOS SDK to automatically ask users for a 1-to-5 star-rating for each version depending on App launch.For this, you need to set StarRatingSessionCount property on CountlyConfig object. When total number of sessions reaches starRatingSessionCount, an alert view asking for 1-to-5 star-rating will be displayed automatically, once for each new version of the app.

config.StarRatingSessionCount = 5;

If you want star-rating dialog to be displayed only once for app lifetime, you can set starRatingDisableAskingForEachAppVersion flag on CountlyConfig object.

 config.StarRatingDisableAskingForEachAppVersion = true;

Additionally, you can customize star-rating dialog message using StarRatingMessage property on CountlyConfig object.

 config.StarRatingMessage = "Would you rate the app?";

Additionally, you can use AskForStarRating method to ask for a star-rating anytime you want.

 Countly.SharedInstance().AskForStarRating((obj) => Console.Write("Rating"));


iTunesConnect IDFA Warning

As Countly iOS SDK source has references to IDFA and iTunesConnect checks for API usage, even if you are not explicitly using IDFA as device ID, you may need to answer Yes for "Does this app use the Advertising Identifier (IDFA)?" question on iTunesConnect app submit form. Please make sure you follow the instructions specified in iTunes Connect Developer Guide - The Advertising Identifier (IDFA) section. Otherwise your app may get rejected due to "Improper use of IDFA" or fail to proceed on app submitting. In screenshot below, you can see which checkboxes to select while sending your app to the App Store :

If you are using an advertisement system, you might need to check "Serve advertisements within the app" checkbox too.

Recording Events

Here is a quick summary on how to use event recording methods.

Regular Events

In examples given below, we will be recording a event named Xamarin studio with different scenarios:

Xamarin studio event occurred 1 times

 Countly.SharedInstance().RecordEvent("Xamarin studio", 12);

Xamarin studio event occurred 12 times

 Countly.SharedInstance().RecordEvent("Xamarin studio", 12);

Xamarin_ios event occured 12 times from country : India , App Version: 1.0 with total amount 20 and for duration .5 sec.

var dict = new NSDictionary("Country", "India", "App_Version", 1.0);
 Countly.SharedInstance().RecordEvent("Xamarin_ios", dict, 12, 20, .5);

Timed Events

In below examples, we will be recording a timed event called Tracking AppRating to track how long it takes to complete:

  • Tracking AppRating started
Countly.SharedInstance().StartEvent("Tracking AppRating");
  • Tracking AppRating ended
 Countly.SharedInstance().EndEvent("Tracking AppRating");

Additionally, you can provide more information like segmentation, count and sum while ending an event.

var dict = new NSDictionary("Country", "India", "App_Version", 1.0);
 Countly.SharedInstance().EndEvent("Tracking AppRating" ,dict,1 ,345);

Duration of the event will be calculated automatically when endEvent method is called.

Push Notifications

Setting up Push Certificate

Please follow iOS, watchOS, tvOS & macOS documentation in order to set up APN credentials in Countly.

Configuring iOS app

Please enable Push Notifications and Remote notifications Background Mode in your app in Entitlement.plist and please make sure that you sign your application using an explicit Provisioning Profile specific to your app's bundleID.

Specify CLYPushNotifications in features array of CountlyConfig object. After that, you'll need to ask for user's permission for push notifications using AskForNotificationPermission() method of Countly, at any point in the app. You need to declare a class and inherit with UIResponder and IUIApplicationDelegate.

After that you need to add code given below in FinishedLaunching method. Countly iOS SDK will handle the rest automatically.

public class AppDelegate : UIApplicationDelegate
	public override bool FinishedLaunching(UIApplication application,                 NSDictionary launchOptions)
            application.WeakDelegate = this;
            //Basic Setting for countly server
            CountlyConfig config = new CountlyConfig();
            config.AppKey = @"your_App_Key";
            config.Host = @"https://YOUR_COUNTLY_SERVER";
            config.Features = new NSObject[] { Constants.CLYPushNotifications };  
            return true;

Rich Push Notifications (iOS10+ only)

Rich push notifications lets you send image, video or audio attachments, as well as customized action buttons on iOS10+. You need to set up Notification Service Extension to use it. Add NotificationServiceExtension in your project and then navigate to NotificationService.cs file.

You also need to add Countly Analytics for Xamarin (iOS) Nuget package into your project.

And add the following line at the end of DidReceiveNotificationRequest() method as shown below:

using CountlySdk;

Please enable Push Notifications in your notificationExtension Entitlement.plist. You need to create an app id and provisioning profile on Apple’s website for your Extension. You also need to configure App Transport Security setting in extension's Info.plist file. Otherwise, media attachments from non-https sources can not be loaded.

Please make sure that you have changed the Deployment Target version of extension target to 10, not 10.3. Otherwise users running iOS versions lower than Deployment Target value can not get rich push notifications.

public override void DidReceiveNotificationRequest(UNNotificationRequest request, 
     Action contentHandler)
            ContentHandler = contentHandler;
            BestAttemptContent =  

            CountlyNotificationService.DidReceiveNotificationRequest(request,               contentHandler);



Deeplinking consists of using a hyperlink that links to a specific piece of content within an app. You can redirect users to any custom page or view in your app, by specifying deeplinks as custom actions button URLs. For this, first, you need to create URL scheme in your project.

To do this, select info.plist -> Advanced -> Url Types.. Enter an identifier (ly.count.countly) into Identifier field. And enter your app's URL (countly) scheme into URL Schemes field.

Then, add the method to your Appdelegate.

In this method you can check the passed url for custom view navigation, using scheme and host properties. For example, if you set custom action button URLs as countly://productA and countly://productB, you can use something similar to this snippet:

public override bool OpenUrl(UIApplication app, NSUrl url, string sourceApp, NSObject annotation)
            if (url.Scheme.Equals("countly"))
                if (url.Host.Equals("productA"))
                  // present view controller for Product A;
                else if (url.Host.Equals("productB"))
                  // present view controller for Product B;
            return true;

When users tap on custom action buttons, Countly iOS SDK will open the specified URLs with your app's scheme. Following this, related method you added to your app's delegate will be called.

Advanced Setup

  • Test Mode

For Development builds, your device will be marked as test device automatically. So, you can send push notifications to test devices by choosing Test Users radio button on Create Message screen of Countly Dashboard.

If you want to manually mark your device as a test device for Distribution builds like TestFlight or AdHoc, you can use IsTestDevice flag on CountlyConfig object.

config.IsTestDevice = true;
  • Disable Alerts Shown by Notification

For disabling automatically showing of messages by CLYPushNotifications feature, you can set doNotShowAlertForNotifications flag on CountlyConfig object. If set, no message will be displayed by using default system UI in the app, but push open event will be recorded automatically.

config.DoNotShowAlertForNotifications = true;
  • Send Push Token Always

Thanks to Remote Notification Background Mode of iOS, it is possible to send silent push notifications to users who have not given notification permission. But Countly iOS SDK does not send push tokens to server by default, from users who have not given permission for notifications. You can change this by setting sendPushTokenAlways flag of CountlyConfig object. If set, push tokens from all users regardless of their notification permission status will be sent to Countly server and these users will be listed as possible recipients on Create Message screen of Countly Dashboard. As these users are not able to be notified by alert, sound or badge, be advised this is useful only for sending data via silent notifications.

config.SendPushTokenAlways = true;
  • Notification Permission with Preferred Types and Callback

As asking for user's permission for push notifications differ by iOS versions, Countly iOS SDK has a one-liner convenience method askForNotificationPermission for both iOS10 and older versions. It simply asks for user's permission for all available notification types. But if you need to specify which notification types your app will use (alert, badge, sound) or if you need a callback to see user's response to permission dialog you can use AskForNotificationPermissionWithOptions() method.

UNAuthorizationOptions authorizationOptions = UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound;
            Countly.SharedInstance().AskForNotificationPermissionWithOptions(authorizationOptions, (arg1, arg2) => Console.WriteLine(arg1));
  • Provide Geolocation [Enterprise Edition only]

Countly lets you send GeoLocation based push notifications to your users. By default, Countly Server uses geoip database to deduce user's location. But, if your app has better means of detecting location, you can send this information to Countly Server by using initial configuration properties or relevant methods.

Initial configuration properties can be set on CountlyConfig object, to be sent on SDK initialization. These are:

Location a CLLocationCoordinate2D struct specifying latitude and longitude. ISOCountryCode an NSString in ISO 3166-1 alpha-2 format country code. City an NSString specifying city name. IP an NSString specifying IP address in IPv4 or IPv6 format.

config.ISOCountryCode = @"IN";
config.City = @"Noida";
config.Location = new CLLocationCoordinate2D(28.5986, 77.3339);
config.IP = @"";

GeoLocation info recording methods also can be called anytime after Countly iOS SDK started. Values recorded using these methods will override the values specified on initial configuration.

Countly.SharedInstance().RecordLocation(new CLLocationCoordinate2D(28.5986, 77.3339));
Countly.SharedInstance().RecordCity(@"India", "IN");

GeoLocation info can also be disabled:


Once disabled, you can re-enable GeoLocation info by calling RecordLocation: or RecordCity: and ISOCountryCode: or RecordIP: method.

Crash Reporting

For using Countly CrashReporting, you'll need to specify CLYCrashReporting in features array on CountlyConfig object before starting Countly.

 config.Features = new NSObject[] { Constants.CLYCrashReporting };

With this feature, Countly iOS SDK will generate a crash report if your application crashes due to an exception, and send it to Countly Server for further inspection. If a crash report can not be delivered to server (e.g. no internet connection, unavailable server), then Countly iOS SDK stores the crash report locally in order to try again later.

For iOS, a crash report includes following information in addition to Countly Analytics already provides:

  • Exception Info:
  • Exception Name
  • Exception Description
  • Stack Trace
  • Binary Images

  • Device Static Info:

  • Device Type
  • Device Architecture
  • Resolution
  • Total RAM
  • Total Disk

  • Device Dynamic Info:

  • Used RAM
  • Used Disk
  • Battery Level
  • Connection Type
  • Device Orientation

  • OS Info:

  • OS Name
  • OS Version
  • OpenGL ES Version
  • Jailbrake State

  • App Info:

  • App Version
  • App Build Number
  • Executable Name
  • Time Since App Launch
  • Background State

  • Custom Info:

  • Crash logs recorded using recordCrashLog: method
  • Crash segmentation specified in crashSegmentation property

You can use crashLog: method to get custom logs with the crash reports.


If you want to use custom crash segmentation you can set optional CrashSegmentation on ConfigObject:

  config.CrashSegmentation = new NSDictionary("Key","value");

You can records handled exception manually, besides automatically reported unhandled exceptions and crashes. You can also manually pass stack trace at the time of handled exception.


Countly Enterprise Feature

This feature is only available with Countly Enterprise subscription.

Symbolication is the process of converting stack trace memory addresses in crash reports, into human readable useful information like class/method names, file names and line numbers.

In order to symbolicate memory addresses, dSYM files for each build needs to be uploaded to Countly Server.

Automatic dSYM Uploading

For Automatic dSYM Uploading, you can use countly_dsym_uploader script in Countly iOS SDK from git.

For this, go to Options section of your app then Build -> Custom Commands, and click on (select a project operation) drop down icon on the top left, then choose New Run Script Phase in the list.

Then, add the following snippet:

COUNTLY_DSYM_UPLOADER=$(/usr/bin/find $SRCROOT -name "countly_dsym_uploader.sh" | head -n 1)

Note: Do not forget to replace your server and app key.

By default Xcode will generate dSYM files for Release build configuration, and countly_dsym_uploader script will handle the uploading automatically. You can check for the result at Report Navigator in Xcode. If dSYM upload is completed successfully, you will see [Countly] dSYM upload succesfully completed. message.

Manual dSYM Uploading

In case of an error with Automatic dSYM Uploading, or just if you want to upload your dSYM files manually, you can use our guide for Manual dSYM Uploading here. You also need to use Manual dSYM Uploading if Bitcode is enabled while uploading your app to the iTunes Connect.

User Profiles

This feature is available with Countly Enterprise subscription.

You can see detailed user information under User Profiles section of Countly Dashboard by recording user details. You can record default and custom properties of user details like this:

//default properties
Countly.User.Name = "John Doe";
Countly.User.Username = "john";
Countly.User.Email = "johndoe@apple.com";
Countly.User.BirthYear = "1974";
Countly.User.Organization = "United States";
Countly.User.Gender = "F";
Countly.User.Phone = "+0123456789";
Countly.User.PictureURL = @"http://s12.postimg.org/qji0724gd/988a10da33b57631caa7ee8e2b5a9036.jpg";
Countly.User.PictureLocalPath = localImagePath;


In addition, you can use custom user details modifiers like this:

Countly.User.Set(@"key101", @"value101");
Countly.User.IncrementBy(@"key102", 5);
Countly.User.Multiply(@"key102", 2);
Countly.User.Max(@"key102", 30);
Countly.User.Min(@"key102", 20);
Countly.User.Push(@"key103", "a");
Countly.User.PushUnique(@"key104", @"uniqueValue");
Countly.User.Pull(@"key103", @"b");


View Tracking

For using Countly AutoViewTracking, you'll need to specify CLYAutoViewTracking in features array on CountlyConfig object before starting Countly:

config.Features = new NSObject[] { Constants.CLYAutoViewTracking };

You can temporarily enable or disable Auto View Tracking using 'IsAutoViewTrackingEnabled' property.

Countly.SharedInstance().IsAutoViewTrackingEnabled = true;

If Auto View Tracking feature is not enabled on initial configuration, enabling or disabling this property later has no effect. It will always be disabled.

Exception View Controllers

By default, following system view controllers will be excluded from auto tracking, as they are not visible views but structural controllers:


In addition to these default exceptions, you can manually add your own exception view controllers using AddExceptionForAutoViewTracking: method by passing view controller class name or title:


If AutoViewTracking feature is not enabled on start configuration, enabling or disabling this property later has no effect.

Manual View Tracking

In addition to AutoViewTracking, you can manually report appearance of a view using ReportView() method with views name:

Countly.SharedInstance().ReportView("my View");

When you report another view, duration of previous view will be calculated and view tracking event will be recorded automatically.


For compatibility with data protection regulations such as GDPR, Countly iOS SDK allows developers to enable/disable any feature at any time, depending on user consent. Currently available features with consent control are:

CLYConsentSessions : sessions CLYConsentEvents : events CLYConsentUserDetails : users CLYConsentCrashReporting : crashes CLYConsentPushNotifications : push CLYConsentLocation : location CLYConsentViewTracking : views CLYConsentAttribution : attribution CLYConsentStarRating : star-rating CLYConsentAppleWatch : accessory-devices

To utilize consents, you should set RequiresConsent flag is set on initial configuration.

config.RequiresConsent = true;

With this flag set, Countly iOS SDK will not collect or send any data automatically, as well as ignoring all manual calls. Until explicit consent is given for a feature, it will be inactive. After giving consent for a feature, it will be started immediately and kept active henceforth.

To give consent for a feature you can use GiveConsentForFeature: method, passing the feature name:


Countly iOS SDK does not persistently store status of given consents. You are expected to handle getting consent from end-users using proper UIs depending on your app's context, and storing them either locally or remotely. Following this, you need to call giving consent methods on each app launch, just after starting Countly iOS SDK, depending on the permissions you managed to get from the end-users.

If the end-user changes his/her mind about consents later, you need to reflect this to Countly iOS SDK, using CancelConsentForFeature: method:


Or, if you want to cancel consent for all the features, you can use CancelConsentForAllFeatures convenience method:


Once consent for a feature is cancelled, that feature is stopped immediately and kept inactive henceforth.

Countly iOS SDK reports consent changes to Countly Server, so Countly Server can do preparations or clean-up on server side as well.

Looking for help?