Once fully configured, the FollowAnalytics SDK allows to track events and attributes, receive and measure push and in-app messages, as well as benefit from deep-linking actions already implemented in the app.

Build configurations

The Followanalytics SDK has 2 compilation modes, matching the debug and release ones defined by Apple.

For the FollowAnalytics SDK:



In FollowAnalytics campaigns, you can specify deep-linking parameters, e.g. in your push messages or for in-app button actions.

These parameters are given to the developer's code by the SDK. It is then up to the developer to implement the deep-linking in the app (specific path of screens, format of the arguments, etc.).

Through the key value format, FollowAnalytics supports both standardized deep-linking (by defining the key you'll always use to give the path), and more direct parameter passing for simpler use cases integrations.

Regular deep-linking is usually implemented using a Router, that will handle the URL called on the app and translate it into the display of the right page, with the right content. An example of an open-source deeplinking router is DeepLinkKit.

Once this Router is configured in your app, the link with the FollowAnalytics SDK can be done the following way, supposing you decide on using the key deeplinking-path to pass your deeplink when creating your campaigns:


  - (void)followAppsShouldHandleParameters:(NSDictionary *)customParameters actionIdentifier:(NSString *)actionIdentifier actionTitle:(NSString *)actionTitle completionHandler:(void (^)())completionHandler
    NSURL *url = [NSURL URLWithString:customParameters[@"deeplinking-path"]];
    if (url)
        [self.router handleURL:url withCompletion:nil];

func followAppsShouldHandleParameters(customParameters: [NSObject : AnyObject]!, actionIdentifier: String!, actionTitle: String!, completionHandler: (() -> Void)!) {

let url:NSURL = NSURL(string: customParameters["deeplinking-path"] as! String)!
self.router?.handleURL(url, withCompletion: nil)


New since version 4.1.0

We've since version 4.1.0 added the possibility to use direct App Links like twitter://messages that will send you to the corresponding screen inside the Twitter application.

You're able to access the functionality by enabling the Deep Linking switch in our UI. There you'll find the field App Link that expects you to enter these type of url schemas. It can either be an URL Schema to an external application or for your own application. In the case of an external application you'll be presented with a system alert asking you to allow the redirection for the target application (the first time only).

Depending of your application's implementation you can now use these App Links to improve your application's usage.

Migrating from 2.* to 3.0.0

To use version 3.0.0+ of the iOS SDK:

- (void)followAppsShouldHandleParameters:(NSDictionary *)openingParameters


- (void)followAppsShouldHandleParameters:(NSDictionary *)customParameters actionIdentifier:(NSString *)actionIdentifier actionTitle:(NSString *)actionTitle completionHandler:(void (^)())completionHandler

These new parameters are available only for iOS 8 and later, They are conform to the notification interactive.

Nothing else changes. Please refer to the sections below for details on the full integration of the SDK.


The SDK requires at least iOS 6 or later. All you need is an Xcode project, the FollowApps.framework file of the SDK and the Settings.bundle if you wish to allow your users to opt-out of usage reports.

Warning – In order to get your logs and view User Analytics data in FollowAnalytics interface in production, for :

Install the SDK

Using Cocoapods

If you use Cocoapods to manage your external dependencies, you have two options: use the public pod, or download the zip to have it locally.

To use the public, online version, simply add the following line to your Podfile:

pod 'FollowApps'

If you'd rather have the file locally, just copy the FollowApps/ directory located in Pod/ to your Xcode project root directory and add the following line to your Podfile in all targets:

pod 'FollowApps', :path => "FollowApps"

Then, you only need to run pod install as usual. If you are starting a new project, do a pod init in the project directory to generate a Podfile.

You can skip the next section and go directly to SDK Configuration .

Manual Installation

  1. Drag and drop the FollowApps.framework in the Frameworks group in the Xcode project navigator (left pane) and check both the Copy box and your target's.

  2. Go to your project configuration, select your target. Under the General pane, add the following frameworks (if not already listed) in the Linked Frameworks and Libraries section:

    • Security.framework
    • SystemConfiguration.framework
    • CoreTelephony.framework
    • CoreLocation.framework
    • PassKit.framework
    • libc++.dylib (before iOs 9) or libc++.tbd (iOS 9 and later)
    • libsqlite3.dylib (before iOs 9) or libsqlite3.tbd (iOS 9 and later)

  3. Under the Build Settings pane, look for the Other Linker Flags entry, and add it the following value: -objC -all_load

  4. To improve the accuracy of your crash reports on the platform, look for Strip style, and set it to Debugging Symbols

  5. Recommended — To allow your user to opt-out of data collection, drag and drop the Settings.bundle file in the Xcode project navigator. It'll add a settings pane in the settings app on their device, in which they will find a switch that they can turn off to disable logging.

    If you already have a settings bundle, simply add the two items from the provided bundle into yours (in the same order).

    Settings bundle localization: In order to add localizations for the Settings bundle the procedure is as follows:

    • Right-click the Settings.bundle in the Finder and click Show Package Contents
    • Duplicate the en.lproj folder and change its name to match the locale you want to add, e.g. fr.lproj for French locale.
    • The files should now appear in Xcode (you may need to open and close the directory hierarchy to get it to refresh). At this point it is simple to edit the Root.strings.

    The French version of the file finishes up like:

    /* Localize the settings strings here if needed */
    "Anonymous usage reports" = "Rapports d'Usage Anonymes";
    "Help us improve the app by sending anonymous usage reports. Your data is not shared with third parties." =
    "Aidez-nous à améliorer l'application en envoyant anonymement les rapports d'usage. Vos données ne seront pas partagées avec des tiers.";
    "Send usage reports" = "Envoyer les rapports";

SDK configuration

Code configuration


In your AppDelegate file, import the <FollowApps/FAFollowApps.h> header file. In your: @interface AppDelegate : UIResponderadd <FAFollowAppsDelegate> and add the following call as the first line of the application:didFinishLaunchingWithOptions: method:

[FAFollowApps configureWithId:@"API_KEY_STRING" debugStateOn:FADEBUG options:launchOptions];
When your app runs in DEBUG mode or in a simulator, the data is automatically sent as development logs, and is therefore not processed to be shown on the main UI page. DEBUG logs can be checked using the method given in the section How to check for Analytics logs? of this documentation.


In your Bridging-Header.h import the <FollowApps/FAFollowApps.h>header file. If you don't have your bridging header file, follows these instructions:

In your AppDelegate.swift, in your:class AppDelegate: UIResponder, add FAFollowAppsDelegate and add the following call as the first line of the application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Boolmethod:

FAFollowApps.configureWithId("API_KEY_STRING", debugStateOn: true/false, options: launchOptions)
If you want to see log information in the console use: debugStateOn: true, if not, use else: debugStateOn: false

If you wish to modify some default settings, take a look at the .h file, which contains comments on everything you can do using the SDK.

URL Scheme to allow full debugging

To allow users to retrieve their device ID for campaign testing and tagging plan debugging, declare a URL Scheme in the info tab of your Xcode project using the bundleId as URL Scheme:

Make sure that it the bundle ID of your app appears in the URL Schemes field as shown in the screenshot.

Once configured, your FA device ID can be obtained by opening the following URI: xxx://followanalytics.com/deviceId, where xxx shall be replaced by the application bundle identifier (com.follow-apps.followme.inHouse in the example above). FA users can request that an e-mail message be sent to their device to facilitate the operation.


The SDK has a validator that will ensure that everything is properly configured.

When your app is running in debug mode, a popup is shown at launch with the details of what is properly configured, and what is not. This makes it easier for you to validate that the various steps were performed properly.

Optional: Session timeout parameter

By default, the maximum time spent outside of the app during a session is set to 120 seconds. If a user exits the app but comes back after 100 seconds, the SDK still considers the session as continuing. If the user only comes back after 121 seconds, then the SDK considers the user stopped what he was doing and starts another session.

You can modify this value by calling:


[FAFollowApps setMaxBackgroundTimeWithinSession:YOUR_SESSION_TIMEOUT_IN_SECONDS];


Note: Larger values might affect the delay before logs arrive to our servers.

AppDelegate access

New since version 4.1.0 - Swift only

If you need to access your application's original delegate you can now use FAFollowApps.applicationDelegate().

Logging user behavior

Logging best practices

The FollowAnalytics SDK allows to save events, using a name, and attach details to it.

Fetch tags from already integrated Analytics solution


The SDK has a feature called AdaptiveSDK: it allows to benefit from logs already in place and use them directly without having to implement a new tagging plan.

The SDK is currently compatible with Mixpanel, Google Analytics, Localytics and Urban Airship. Use


[FAFollowApps detectedSDKs];


to check that our SDK detects the current integration you have in place.

Then, you can select manually the SDK you want to get tags from:

for instance by calling


[FAFollowApps fetchTagsFromSDKs:FASDKMixpanelKey];

to use a tagging plan you have defined using Mixpanel.

You can also use


[FAFollowApps fetchTagsFromSDKs:[FAFollowApps detectedSDKs]];


to fetch all tags from compatible SDKs.

How it works

All the events you save using the compatible Analytics SDKs will also be saved on FollowAnalytics. The event name will be prefixed with a two-character code identifying the source: UA for UrbanAirship, LL for Localytics, and so on.

Just like for events tagged directly with our SDK, you can see logs in your developer console when a log is saved, so that you can check it is properly working.

Regular, native event logging

The SDK allows you to log events happening in your code. These are the two methods you can call on the SDK:


+ (BOOL)logEventWithName:(NSString *)name details:(id)details;
+ (BOOL)logErrorWithName:(NSString *)name details:(id)details;


FAFollowApps.logEventWithName(name: String!, details: AnyObject!)
FAFollowApps.logErrorWithName(name: String!, details: AnyObject!)

Use the name as the unique identifier of your tag, use the details section to add specific details to your tag. Once your tags is referenced on the web interface, you'll be able to rename and group them for display.

For instance, logging the appearance of a view could be done the following ways:


[FAFollowApps logEventWithName:@"Product view" details:@"Product reference"];
[FAFollowApps logEventWithName:@"In App purchase completed" details:@"Full pack"];

FAFollowApps.logEventWithName("product view", details: "Product reference")
FAFollowApps.logErrorWithName("In App purchase completed", details: "Full pack")

In debug mode, the SDK will acknowledge the saving by writing in the console whatever it receives. If the parameters sent to these methods are over 60Kb, the method will refuse them, return NO, and write a message in the console if it is running in debug mode.

Logging additional information

The FollowAnalytics SDK allows you to store additional information for a single event. Whenever you need to store additional information about an event use a NSDictionary to store the keys and values it contains.


NSDictionary *detail_dictionary = @{ key_1: obj_1, key_2 : obj_2, key_3 : obj_3};
[FAFollowApps logEventWithName:@"Example log name" details:detail_dictionary];
let detail_dictionary:NSDictionary = [key_1: obj_1, key_2: obj_2, key_3: obj_3]
FAFollowApps.logEventWithName("Example log name", details: detail_dictionary)

If you try to pass anything else than a dictionary or a string, the method will return NO. If you have compiled in debug mode, it will print a message in your developer console.

Logging from a web view

If you happen to use a web view to display elements of your app, you can also tag events and errors from within your HTML/JS code. To do so:

  1. Make sure you use the FAWebView, both in your .h file and your .xib or Storyboard, instead of the regular UIWebView. For the latter, you need to set the Custom Class parameter of your UIWebView to FAWebView in the Identity Inspector.

  2. Use the provided FAWebView.js in your web page code to save events. For instance, you could do:

        <a href="#" onclick="FALogEvent('My event', 'My event details')">Log an event</a>
        <a href="#" onclick="FALogError('My error', '')">Log an error</a>
        <a href="#" onclick="FALogEvent('My event', {'hello': 'Hi', 'How are you': 'good!'})">Log an event with hash</a>
  1. In case you want to register for push through a webview, you need to call FARegisterForPush(), like for instance: <a href="#" onclick="FARegisterForPush()">register for push</a>

User ID

If users can sign in somewhere in your app, you can specify their identifier to the SDK. This way, you will be able to relate crashes to specific users, link your users between FollowAnalytics and your CRM, and more.

To do so, use


+ (void)setUserId:(NSString *)userId;
func setUserId(userId: AnyObject!)

If you want to remove the user identifier (in case of a sign out for instance) please use the method


+ (void)unsetCurrentUserIdentifier;


  func unsetCurrentUserIdentifier

Predefined attributes

The SDK allows to set values to both custom and predefined attributes.

For predefined attributes, the SDK has the following properties:

    + (void)setUserFirstName:(NSString *)firstName;
    + (void)setUserLastName:(NSString *)lastName;
    + (void)setUserEmail:(NSString *)email;
    + (void)setUserDateBirth:(NSDate *)dateBirth;
    + (void)setUserGender:(FAGender)gender;
    + (void)setUserCountry:(NSString *)country;
    + (void)setUserCity:(NSString *)city;
    + (void)setUserRegion:(NSString *)region;
    + (void)setUserProfilePictureUrl:(NSString *)url;

They are "predefined" in the sense that they will be attached as default fields on your user profiles.

For example, to set user city as "Paris" for user Joe, you would proceed as follows:

    [FAFollowApps setUserFirstName:@"Joe"];
    [FAFollowApps setUserCity:@"Paris"];

Custom attributes

Double check your custom attribute types

When a value for an unknown attribute is received by the server, the attribute is declared with the type of that first value.

If you change the type of an attribute in the SDK, values might be refused server-side. Please ensure the types match by visiting the profile data section of the product.

Set a custom attribute

To set your custom attributes, you can use methods that are adapted for each type:

+ (void)setInt:(NSInteger)intValue forKey:(NSString *)key;
+ (void)setDouble:(double)doubleValue forKey:(NSString *)key;
+ (void)setBoolean:(BOOL)booleanValue forKey:(NSString *)key;
+ (void)setDate:(NSDate *)dateValue forKey:(NSString *)key;
+ (void)setDateTime:(NSDate *)dateValue forKey:(NSString *)key;
+ (void)setString:(NSString *)stringValue forKey:(NSString *)key;

For example, to set the user's job:

[FAFollowApps setString:@"Taxi Driver" forKey:@"key_job"];

FAFollowApps.setString("Taxi Driver", forKey:"key_job")
Delete a custom attribute value

You can delete the value of an attribute using its key. For example, to delete the user's job:

[FAFollowApps removeCustomUserAttributeForKey:@"key_job"];

Set of Attributes

You can add or remove an item to or from a set of attributes.

To add an item:

NSSet *set = [[NSSet alloc] initWithObjects:@"apple", @"strawberry", @"lemon", nil];
[FAFollowApps addCustomUserAttributeSet:set forKey:@"fruits"];

let set:NSSet = NSSet(array: ["apple", "strawberry", "lemon"])
FAFollowApps.addCustomUserAttributeSet(set as Set<NSObject>, forKey: "fruits")

To remove an item:

[FAFollowApps removeCustomUserAttributeSet:@"lemon" forKey:@"fruits"]; // Removes "lemon" from set of fruits.

FAFollowApps.removeCustomUserAttributeSet("lemon", forKey: "fruits")

And to clear a set:

[FAFollowApps deleteCustomUserAttributeSetForKey:@"fruits"]; // Removes all the items from the set and deletes it.


For further information, refer to the SDK header file.

Cordova/PhoneGap event logging


While the basic setup only takes one line of code, one aspect of the FollowAnalytics SDK has to remain in the hands of the app developer: prompting the user for Push notification authorization.

If you already do it for other purposes, nothing to do here. Otherwise, simply add the following line after the configuration one you added previously:


[FAFollowApps registerForPush];

There is nothing else to do, FollowAnalytics will handle its own notifications and you will still receive yours, as long as you compile with the appropriate Push certificates, and provide FollowAnalytics with the required .pem file. To generate the pem push certificate required for FollowAnalytics, you can follow the Certificates section in this tutorial.

Important: If you register interactive notification categories and use our registerForPush method, make sure you register categories after calling registerForPush.

NOTE – Please keep in mind that the FollowAnalytics SDK does not manage the application's badge. You'll have to manage them inside your application code.

In order to remove the badge number in your application icon and clean the Notification Center entries for Notifications use the following code:


[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
UIApplication.sharedApplication().applicationIconBadgeNumber = 0


Handling Custom Parameters

FollowAnalytics Campaigns allow to define custom parameters, used for deep-linking.

A common use case is to open a custom screen from a notification. For example, the end user receiving a notification saying 'Product X has a new price, check it out!' would have a richer experience if this notification was linking directly to the right product page in the application once tapped. Custom parameters can also be sent after the user has tapped a button on an in-app message.

Upon reception of a notification with custom parameters, or when an action button of an in-app message has custom parameters associated, the following method of the FAFollowappsDelegate is called:


- (void)followAppsShouldHandleParameters:(NSDictionary *)customParameters actionIdentifier:(NSString *)actionIdentifier actionTitle:(NSString *)actionTitle completionHandler:(void (^)())completionHandler;
func followAppsShouldHandleParameters(customParameters: [NSObject : AnyObject]!, actionIdentifier: String!, actionTitle: String!, completionHandler: (() -> Void)!)

Implement this method to be able to act upon these custom parameters.

Get custom parameters from last notification

Some applications might not be able to receive the notification custom parameters. Although unlikely, you can call [FAFollowApps lastPushCampaignParams] to get the latest NSDictionary containing the custom parameters passed by the Notification.

Note this is a one shot call as a second call to this method will return an empty NSDictionary.

Interactive notifications (iOS 8)

To allow for interactive notifications, you need to register actions in your code, the same way you would for your own notifications:


    UIMutableUserNotificationCategory *category = [[UIMutableUserNotificationCategory alloc] init];
    category.identifier = @"categoryIdentifier1";
    [category setActions:actionsArray forContext:UIUserNotificationActionContextDefault];
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:[NSSet setWithObjects:category, nil]];
    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];

    let category:UIMutableUserNotificationCategory = UIMutableUserNotificationCategory()
    category.identifier = "categoryIdentifier1"
    category.setActions(actionsArray, forContext:UIUserNotificationActionContext.Default)
    let settings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: Set(arrayLiteral: category))

If a user receives an interactive notification and taps one of the buttons, it calls the followAppsShouldHandleParameters:actionIdentifier:actionTitle:completionHandler: method and passes the action identifier and title. If no custom parameter was defined when creating the campaign, the first parameter is an empty dictionary.

The completionHandler comes from the default interactive notification handling methods. Make sure you call it if it is not nil as it won't be called by FA if passed to you.

Important: If you register interactive notification categories and use our registerForPush method, make sure you register categories after calling registerForPush.

Custom Rich Campaigns

Rich campaigns can be handled directly by the application code, instead of being showed automatically by the SDK. The behavior is defined when creating the campaign, using the "automatically display content" switch.

For campaigns where the content is not handled by FollowAnalytics, implement the following FAFollowAppsDelegate method in your AppDelegate:


- (void)followAppsShouldHandleWebViewUrl:(NSURL *)url withTitle:(NSString *)webviewTitle;

func followAppsShouldHandleWebViewUrl(url: NSURL!, withTitle webviewTitle: String!)

You can stop the display of Rich Campaigns in screens where you don't want them to appear. In order to do this call the


[FAFollowApps pauseRichCampaignDisplay]


Whenever you want to display them, just call the


[FAFollowApps resumeRichCampaignDisplay]


Getting your device ID for testing push notifications

FollowAnalytics allows you to send push messages to a specific device in order to test your campaigns, before broadcasting the message to your targeted audience.

To do so, you therefore need to be able to retrieve the device identifier associated to your app, on your device.

If you want to make it available from your app (for instance through a long press on some part of a view), you can get it programmatically through:


[FAFollowApps deviceUUID]


However, if you want non-developer users to retrieve the device id, declare a URL Scheme as explained at step 5 of the manual configuration section of this document.

Attribution Analytics

TUNE (previously MobileAppTracking)

Please refer to the TUNE(MobileAppTracking) documentation to integrate their SDK. To link TUNE attribution data with usage data measure by FollowAnalytics you need to set the Tune userId with FollowAnalytics deviceId:


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

    // Be sure to instantiate FollowAnalytics' SDK before instantiating TUNE's SDK
[FAFollowApps configureWithId:API_KEY_STRING debugStateOn:FADEBUG options:launchOptions];

    // TUNE SDK Configuration at https://developers.mobileapptracking.com/ios-sdk/

return YES;

- (void)applicationDidBecomeActive:(UIApplication *)application
    // Make sure to set FollowAnalytics' userId before calling the Tune's measureSession
    [Tune setUserId:[[FAFollowApps deviceUUID] UUIDString]];
    // Tune will not function without the measureSession call included
    [Tune measureSession];


func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Be sure to instantiate FollowAnalytics' SDK before instantiating TUNE's SDK

FAFollowApps.configureWithId(API_KEY_STRING, debugStateOn: false, options: launchOptions)

// TUNE SDK Configuration at https://developers.mobileapptracking.com/ios-sdk/

return true

func applicationDidBecomeActive(application: UIApplication) {
// Make sure to set FollowAnalytics' userId before calling the Tune's measureSession

// Tune will not function without the measureSession call included

How to check User Analytics logs?

Once your app has been configured with the right API Key, you can start logging immediately.

If you run your application compiled in Release mode, on a device, the logs will end up on the platform.

IMPORTANT – You should always compile the application in Release before submitting to the store.