Prerequisites and minimal setup

In this section, we explain how to get started with FollowAnalytics SDK for iOS. Before you start, be sure to have all the necessary prerequisites. These include:

  • Registering the application on the Platform
  • Generating the API Key

Here are the minimal steps for integrating the SDK in your app:

Once the integration is finished, we highly recommend you test the setup. You will find out how to test your setup in this section. Then, you can start tagging events and saving attributes in your app.

Installation with Cocoapods

Starting with CocoaPods

The best way to install the SDK is with CocoaPods. This will allow you to easily update the SDK when new versions are released. If you have not installed CocoaPods yet, you may refer to the this site, where you can install Cocoapods (1.1.0 or later).

Before you start, be sure to have a Podfile. You could create one by writing pod init in your terminal in your project. To open your Podfile, you could find it in your Workspace, or by writing open -a Xcode Podfile in the terminal.

  1. Add pod 'FollowAnalytics ~> 6.2.0' in the Podfile (see screenshot below)

  2. Run pod repo update from the command line. This will enable CocoaPods to detect the latest available version of FollowAnalytics.

  3. Run pod install

Now FollowAnalytics is successfully installed.

Use the .xcworkspace file

To open your project with Xcode, use the .xcworkspace file generated by CocoaPods.

Initialize the SDK with your API key

Prerequisites: Have your API key

Be sure to have your API key for this step of the configuration. You can retrieve you app's API key from the administration section of the FollowAnalytics platform.

  1. Import the FollowAnalytics framework in your AppDelegate.

  2. Inside your UIApplicationDelegate implementation, create a configuration object and set the required fields

  3. Just bellow the configuration object, start the SDK

Your code should look like this:


#import <FollowAnalytics/FollowAnalytics.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication*)application
  didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
  // ....
  // as early as possible
  FollowAnalyticsConfiguration* configuration = [FollowAnalyticsConfiguration
    configurationWith:^(FollowAnalyticsMutableConfiguration* _Nonnull c) {
      c.apiKey = @"YOUR API KEY";
      c.isVerbose = true; // Before publishing the app, set isVerbose to false
  [FollowAnalytics startWithConfiguration:configuration startupOptions:launchOptions];
// ..


import FollowAnalytics
class AppDelegate: UIResponder, UIApplicationDelegate {
  func application(_ application: UIApplication, didFinishLaunchingWithOptions
    launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // ....
    let configuration = FollowAnalyticsConfiguration.init { (c) in
      c.apiKey = "YOUR API KEY"
      c.isVerbose = true // Before publishing the app, set isVerbose to false
    FollowAnalytics.start(with: configuration, startupOptions: launchOptions)
    // ....

You can configure the SDK with all the available parameters which you can find here.

Troubleshooting: integrating in projects using Firebase

The FollowAnalytics SDK proxies the application's delegate. If you are changing the default app delegate, make sure to do so before initializing the FollowAnalytics SDK. Your application may behave erratically if you don't.

Other SDKs, like Firebase, may swizzle your applications' methods by default. In order to have both FollowAnalytics and Firebase SDK working properly in your app, make sure you set the FirebaseAppDelegateProxyEnabled to NO in you app's Info.plist.

Necessary project capabilities

Preparing your project for FollowAnalytics

These methods and settings are necessary to your app in order to use the FollowAnalytics SDK. These include:

  • Adding push notification capabilities in the project settings
  • Calling the push notification method for displaying push notifications
  • Enabling device geolocation
  • Defining the URL Scheme for acquiring the device ID

Enabling Push notification capabilities

In the Capabilities tab of your Xcode Project:

  1. Enable Push Notifications by setting the switch to ON.

  2. Enable the Remote notifications capability in the Background Modes:

    This will ensure that FollowAnalytics can detect uninstalls and send Silent Push Notifications.

Display the notifications

In order to display notifications on the screen of your app, the operating system requires a permission from the user. Enable this by calling the requestNotificationCenterDefaultAuthorisation method.


[FollowAnalytics requestNotificationCenterDefaultAuthorisation]



Without this request, notifications will be sent to the app as a silent notification.

Device Location

FollowAnalytics will only access the location if you give the permission to the SDK. If you are already using it and want to share it with FollowAnalytics you will have to call : enableGeofencing.


[FollowAnalytics enableGeofencing]



Define the URL scheme

To allow the user to retrieve the device ID for testing from the platform, declare a URL Scheme in the info tab of your Xcode project using the bundleId of your app as URL Scheme:

  1. Go to the info tab of the project targets.

  2. At the bottom you select the subsection called "URL Types".

  3. Click the + sign at the bottom.

  4. Add the bundle ID of your app in both identifier and URL Schemes fields

URL Scheme

Once configured, your FollowAnalytics device ID can be obtained by opening the following URI: YourURLScheme://, with YourURLScheme as the application bundle ID.

Now, users can add devices to the platform by registering without needing to know the device ID. From the platform, they will send an email a link that will open the app and allow them to register the device.

Test your setup

Before you skip this section

We highly recommend you test your setup before you start adding analytics and campaign features to your app. These steps will help you understand how the SDK works and provide you with ways to better use the FollowAnalytics SDK.

Now that you have the SDK installed and the requirements fulfilled, you can test your setup with the tools we provide.

Validate your setup

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 time 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.

To know more about what the validator checks and how, please refer to its dedicated page.

Using the Device Observer

You can test your push notifications by using the Device Observer. You can access the Device Observer by going to Administration > Test Devices and click on your device. There you will find live logs coming from the SDK and send a default push notification.

Your device must be registered in order to use the observer. You can register devices from the "Test Devices" page.

You can find more on the Device Observer here.

Test Crash reporting

To simulate a crash of your device, you can create an empty array and try to access its item at index 0. This will crash your device. When reloading the app, you will see a Crash report sent to FollowAnalytics servers.

    NSArray *array = [NSArray new];
    id obj2 = [array objectAtIndex:0]; // this line crashes
    let array = [String]()
    print(array[0]) // this line crashes

To verify that the crash configuration is working properly, launch your app without the debugger. i.e. manually on the device or from the simulator, without using the "run" button in Xcode.


Events vs Attributes

The FollowAnalytics SDK allows you to tag both events and attributes. In this section, we explain how to utilize both of them in your app and benefit from analytics capabilities. If you are unsure about the difference, you may refer to the corresponding FAQ entry.

Data sent in debug mode will not appear on dashboards

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 FAQ section (see related entry in FAQ for more information on debug & release modes).

App tags

You can tag your app by adding logs to specific events and errors experienced by the user. These logs are then received and visible on the FollowAnalytics platform.

Logging best practices

To successfully empower your team with FollowAnalytics make sure your logs are relevant, please read the Logging best practices entry in the FAQ section.

Regular, native event tagging

To add FollowAnalytics logs in your code, here are the two methods you can call from the SDK:


+ (void)logEvent:(nonnull NSString*)name details:(nullable id)args;
+ (void)logError:(nonnull NSString*)name details:(nullable id)args;


FollowAnalytics.logEvent(name: String!, details: AnyObject!)
FollowAnalytics.logError(name: String!, details: AnyObject!)

Use the name as the unique identifier of your log. Use the details section to add specific details or context. The details field can either be a String or a Hash, so that you can associate multiple key-values for additional context.

Events can be renamed on the FollowAnalytics platform

The name that you give to your event here can be overridden in the FollowAnalytics platform. For more information, reach out to your Customer Success Manager or message support.

For example, you can log the display of a view by writing the following:


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

NSDictionary *detail_dictionary = @{ key_1: obj_1, key_2 : obj_2, key_3 : obj_3};
[FollowAnalytics logEvent:@"Example log name" details:detail_dictionary];


FollowAnalytics.logEvent("product view", details: "Product reference")
FollowAnalytics.logError("In App purchase completed", details: "Full pack")

let detail_dictionary:NSDictionary = [key_1: obj_1, key_2: obj_2, key_3: obj_3]
FollowAnalytics.logEvent("Example log name", details: detail_dictionary)

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.

Tagging from a web view

If your app contains web views, you can also tag events and errors from within your HTML/JS code. Our solution integrates itself inside a WKWebView. Here, you have a selection of JavaScript methods that you can use:


FollowAnalytics.logError('err1','str value')
FollowAnalytics.logEvent('event1','str value')

The complete list of JavaScript methods is documented in FAWKWebViewJSBridge.h .

In order to use it, you need to do the following:


// Setup: Adopt WKUIDelegate protocol in your object of choice, typically a UIViewController.
// The rest of the steps assume that you are in a UIViewController context.
@interface ViewController <WKUIDelegate>
// ...

// Step 1: At the initialization of the hosting view controller, keep a strong reference to our FAWKWebViewJSBridge:
self.webViewJSBridge = [[FAWKWebViewJSBridge alloc] init];
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
// Set up your configuration as needed.
// ...
// Step 2: give us your configuration in order for us to do our side of the setup
[self.webViewJSBridge addToConfiguration:configuration];
// Step 3: make sure that you use the configuration for the WKWebView
WKWebView* webView = [[WKWebView alloc] initWithFrame:frame configuration:configuration];
// Step 4: set your controller as a UIDelegate
webView.UIDelegate = self;

// Step 5: Implement the delegate method
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable result))completionHandler{
if([prompt hasPrefix:@"FollowAnalytics"]){
  [self.webViewJSBridge webView:webView runJavaScriptTextInputPanelWithPrompt:prompt defaultText:defaultText initiatedByFrame:frame completionHandler:completionHandler];
// Step 6(Optional): If you are using JavaScript method prompt in your JavaScript code, make sure that you implement an alternative
// for such cases, for example by using a UIAlertView

User ID and attributes

This section covers the integration of a user ID and customer attributes. The SDK allows you to set values for attributes FollowAnalytics has predefined as well as custom attributes which you can make yourself.

You don't need a user ID to set attributes

Attributes are tied to the device when no user ID is provided. If a user ID is set, a profile is created server-side and can be shared across apps.

In both cases, attributes can be used in segments and campaigns to target users.

User ID

What is a user ID?

If users can sign in somewhere in your app, you can specify their identifier to the SDK. Unique to each user, this identifier can be an e-mail address, internal client identifier, phone number, or anything else that ties your customers to you. This is what we call the user ID.

A user ID enables you to relate any event to a specific user across several devices. It is also an essential component for transactional campaigns. A common user ID enables you connect to a CRM or other external systems.

To get or set the user identifier, use the following methods available on FollowAnalytics class:


+ (void)setUserId:(nullable NSString*)userId;
+ (nullable NSString*)getUserId;


open class func setUserId(_ userId: String?)
open class func getUserId() -> String?

Predefined attributes

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

For predefined attributes, the SDK has the FollowAnalyticsUserAttributes protocol with the following properties:

- (void)setFirstName:(nullable NSString*)firstName;
- (void)setLastName:(nullable NSString*)lastName;
- (void)setEmail:(nullable NSString*)email;
- (void)setDateOfBirth:(nullable NSDate*)dateOfBirth;
- (void)setGender:(FollowAnalyticsGender)gender;
- (void)setCountry:(nullable NSString*)country;
- (void)setCity:(nullable NSString*)city;
- (void)setRegion:(nullable NSString*)region;
- (void)setProfilePictureUrl:(nullable NSString*)profilePictureUrl;

The FollowAnalyticsUserAttributes is implemented by FollowAnalytics.userAttributes so you can use it.

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

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

[FollowAnalytics.userAttributes setFirstName:@"Joe"];
[FollowAnalytics.userAttributes setCity:@"Paris"];

Custom attributes

In addition to predefined attributes, you can add your own custom attributes to your code.

Always 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. Ensure the attribute types match. This could be done by comparing with the ones you have in the profile data section of the product.

Set a custom attribute

To set your custom attributes, you can use these additional methods from FollowAnalyticsUserAttributes protocol that are adapted for each type:

- (void)setInteger:(NSInteger)integerValue forKey:(nonnull NSString*)key;
- (void)setDouble:(double)doubleValue forKey:(nonnull NSString*)key;
- (void)setString:(nonnull NSString*)string forKey:(nonnull NSString*)key;
- (void)setBoolean:(bool)boolean forKey:(nonnull NSString*)key;
- (void)setDate:(nonnull NSDate*)date forKey:(nonnull NSString*)key;
- (void)setDateTime:(nonnull NSDate*)dateTime forKey:(nonnull NSString*)key;
- (void)clear:(nonnull NSString*)key;
- (void)add:(nonnull NSSet<NSString*>*)values toSet:(nonnull NSString*)key;
- (void)remove:(nonnull NSSet<NSString*>*)values toSet:(nonnull NSString*)key;
- (void)clearSet:(nonnull NSString*)key;

For example, to set the user's occupation:

[FollowAnalytics.userAttributes setString:@"Taxi Driver" forKey:@"occupation"];
Delete a custom attribute value

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

[FollowAnalytics.userAttributes  clear:@"occupation"];
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];
[FollowAnalytics.userAttributes add:set toSet:@"fruits"];

To remove an item:

[FollowAnalytics.userAttributes remove:@"lemon" toSet:@"fruits"]; // Removes "lemon" from set of fruits.

And to clear a set:

[FollowAnalytics.userAttributes clearSet:@"fruits"]; // Removes all the items from the set.

For further information, refer to the SDK header file.

Opt-Out Analytics

What is Opt-out analytics?

The SDK can be configured to no longer track user information. This is what we call to opt out of analytics.

Once opted-out, no new data is collected, nor is it stored in the app. New session are not generated at launch and nothing is sent back to the server. This data includes the following:

  • tagged elements such as events, errors
  • new user identification and attributes
  • crash reports

When a user is opted-out of analytics, campaigns will continue to work with the following limitations:

  • No Contextual campaigns - as they depend on log tracking
  • No Transactional campaigns - as they depend on the user ID
  • No Dynamic campaigns - as they depend on users entering a segment
  • Campaigns filters will depend on old data (before the user opted-out)

All data collected before the user has opted-out is preserved within FollowAnalytics servers. This means that a user having opted-out will still receive campaigns based on data acquired before opting out (previous campaigns, existing segments, etc). The opt-in state is persisted between app starts (unless storage of the app is emptied).

To inspect and set the opt-out state, call the following methods on FollowAnalytics class:

+ (BOOL)getOptInAnalytics;
+ (void)setOptInAnalytics:(BOOL)optInAnalytics;

Please see additional doc in the new FollowAnalytics and FollowAnalyticsConfiguration interface for more details.

Additionally, if the opt-in by default policy doesn't suit your use case you can change it by setting the optInAnalyticsDefault on FollowAnalyticsConfiguration.

@property(nonatomic, readonly, assign) BOOL optInAnalyticsDefault;


You can record when the user expresses his demand to access or delete his personal data by calling one of the following methods:

[FollowAnalytics.GDPR requestToAccessMyData]
[FollowAnalytics.GDPR requestToDeleteMyData]

The SDK will record all requests and send them to FollowAnalytics servers as soon as network conditions allow it. The SDK remembers pending requests between app restarts.


Campaign basics

What we mean by campaigns are the messages that you with to send to your user from the FollowAnalytics platform. Currently, FollowAnalytics enables you to send two types of campaigns: push notifications and in-app messages. Push notifications allow you to send messages to your user's home screen, whereas an in-app a message that is displayed in the app while the user is actively using it.

Before you start, be sure that the SDK is properly initialized. This includes registration for push notifications, which is covered in the integration section.

In this section, we cover all you need for your app to receive the campaigns sent from the FollowAnalytics platform, and how you can add the features the fully take of advantage the SDK's capabilities.

Rich push notifications

Rich push notifications on iOS

Rich push notifications are notifications with embedded rich media (images, GIFs, videos). They are only available on iOS 10 and above. Should a user have a version under iOS 10, they will receive rich push notifications but not be able to see the rich media included.

Notification Service Extension Framework


To make your app able to receive rich notifications & badge incrementation, follow these steps:

  1. In your xCode project, add a new target.

  2. Select Notification Service Extension, give it a name and confirm. Then when prompted, activate the scheme.

Install using Cocoapods
  1. If you want to use Cocoapods to manage your external dependencies, simply add the following line to your Podfile only in the extension target:

    pod 'FANotificationExtension'

    If you don't have a podfile yet, open a console and do a pod init in your project directory.

    Then, you only need to update your cocoapods dependencies:

    pod install
  2. Select the target of your main app, in Build phase

    1. Press the + button, and select New Copy File Phase.
    2. Change the destination to Frameworks
    3. Add the FANotificationExtension.framework, you should find it inside the Pod folder.
  3. Still in the Build phase

    1. Press the + button, and select New Run Script Phase.
    2. Add this script:
      bash "${PODS_ROOT}/FANotificationExtension/FANotificationExtension.framework/"

Copy and paste the code underneath.


#import “NotificationService.h”
#import <FANotificationExtension/FANotificationExtension.h>

@interface NotificationService ()

@property(nonatomic, strong) void (^contentHandler)(UNNotificationContent* contentToDeliver);
@property(nonatomic, strong) UNMutableNotificationContent* bestAttemptContent;


@implementation NotificationService

- (void)didReceiveNotificationRequest:(UNNotificationRequest*)request
   withContentHandler:(void (^)(UNNotificationContent* _Nonnull))contentHandler {
    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];
                            completion:^(UNMutableNotificationContent* _Nullable newContent) {
                            NSLog(@"NotificationService: %@", request);
                            // Modify the notification content here...


- (void)serviceExtensionTimeWillExpire {
    // Called just before the extension will be terminated by the system.
    // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the
    // original push payload will be used.


import UserNotifications
import FANotificationExtension

class NotificationService: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

        if let bestAttemptContent = bestAttemptContent {
            // Modify the notification content here...
            bestAttemptContent.title = "\(bestAttemptContent.title) [modified]"

            var urlString:String? = nil
            if let urlImageString = request.content.userInfo["urlImageString"] as? String {
                urlString = urlImageString

            if urlString != nil, let fileUrl = URL(string: urlString!) {
                print("fileUrl: \(fileUrl)")

                guard let imageData = NSData(contentsOf: fileUrl) else {
                guard let attachment = UNNotificationAttachment.saveImageToDisk(fileIdentifier: "image.jpg", data: imageData, options: nil) else {
                    print("error in UNNotificationAttachment.saveImageToDisk()")

                bestAttemptContent.attachments = [ attachment ]
                FANotificationService.getFAContentIfNeededWithRequest(request, BestAttemptContent, appGroup, contentHandler)


    override func serviceExtensionTimeWillExpire() {
        // Called just before the extension will be terminated by the system.
        // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {


@available(iOSApplicationExtension 10.0, *)
extension UNNotificationAttachment {

    static func saveImageToDisk(fileIdentifier: String, data: NSData, options: [NSObject : AnyObject]?) -> UNNotificationAttachment? {
        let fileManager = FileManager.default
        let folderName = ProcessInfo.processInfo.globallyUniqueString
        let folderURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(folderName, isDirectory: true)

        do {
            try fileManager.createDirectory(at: folderURL!, withIntermediateDirectories: true, attributes: nil)
            let fileURL = folderURL?.appendingPathComponent(fileIdentifier)
            try data.write(to: fileURL!, options: [])
            let attachment = try UNNotificationAttachment(identifier: fileIdentifier, url: fileURL!, options: options)
            return attachment
            } catch let error {
            print("error \(error)")
        return nil

Badge management

What are badges?

Badges are small red indicators displayed at the top right-hand corner of the app icon. FollowAnalytics enables you to use badges, so that every time you send a push notification, appears or the value of the badge is incremented. Once enabled, badges are added by turning on the 'badge' switch at the creation of the campaign from the FollowAnalytics platform.


For using this feature, there are 3 prerequisites:

  • Have the Notification Service Extension with the FollowAnalytics extension framework. More information here
  • Create an app group between your app and the extension.
  • Specify your app group in the init (configureWithId...)

In order to enable badges, add the following call:


[FABadge enable];



By default, the value of the badge is incremented by 1 when a push is received. In order to update that value differently or reset the value, implement the following methods:


[FABadge setBadge:INTEGER]; // Set the value of the icon badge number
[FABadge updateBadgeBy:INTEGER]; // Update the value of the icon badge number
[FABadge badge]; // Get the value of the icon badge number

FABadge.setBadge(Int) // Set the value of the icon badge number
FABadge.updateBadgeBy(Int) // Update the value of the icon badge number
FABadge.badge // Get the value of the icon badge number

Enable badges in rich push notifications

If you need to increase the badge number with a push:

  1. Create an App Groups between your main App and you extension.
  2. Enable app group capability in the App IDs of your main application and your notification service extension. The app group should be the same in main application and notification service extension.
  3. Activate the app group capability in XCode project configuration, and add the corresponding app group bundle.
  4. Re-download all the provisioning profiles for application and notification service extension.

Deep-linking: URL, Parameters

Campaigns created through FollowAnalytics allow to deep link to content in an app. This could be for your app or a third party. For this you can use specific deep-linking features you will find explained here.

Direct App links

Version 4.1.0 of the SDK introduced the possibility to use direct App Links like twitter://messages, which will send you to the corresponding screen inside the Twitter app. You can use this feature by adding the deep-link in the "Advanced Options" the FollowAnalytics platform, when creating a campaign.

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).

If the App Link is a deep link to your app, you can set the onOpenURL callback on the configuration, in order for you to be able to chose when your app is ready to execute the App links. If you chose to do so, make sure to eventually call the given callback or else the URL opening will not happen.

⚠️This callback is only called when the the appLink is called from a notification


FollowAnalyticsConfiguration* configuration =
  [FollowAnalyticsConfiguration configurationWith:^(FollowAnalyticsMutableConfiguration * _Nonnull mutableConfiguration) {
    mutableConfiguration.onOpenURL = ^(void (^ _Nonnull openURLBlock)(void)) {
      // ...
[FollowAnalytics startWithConfiguration:configuration startupOptions:startupOptions];


let configuration = FollowAnalyticsConfiguration.init { (cfg) in
  cfg.environment = environment
  cfg.onOpenURL = { (openURLBlock) in
    // ...
FollowAnalytics.start(with: configuration, startupOptions: launchOptions)

Deep-linking parameters

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.).

In order to access the deep-link parameters, implement the onIncomingDeepLink callback on FollowAnalyticsConfiguration.

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 in the app. The router will translate it into the display of the right page, with the right content. An example of an open-source deep-linking 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 deep-link when creating your campaigns:


FollowAnalyticsConfiguration* configuration = [FollowAnalyticsConfiguration
  configurationWith:^(FollowAnalyticsMutableConfiguration* _Nonnull mutableConfiguration) {
    mutableConfiguration.onIncomingDeepLink = ^(NSDictionary * _Nullable parameters,
    NSString * _Nullable actionIdentifier, NSString * _Nullable actionTitle,
    void (^ _Nullable completionHandler)(void)) {
      NSURL *url = [NSURL URLWithString:customParameters[@"deeplinking-path"]];
      if (url)
          [self.router handleURL:url withCompletion:nil];


let configuration = FollowAnalyticsConfiguration.init { (cfg) in
  cfg.onIncomingDeepLink = {
    (parameters, actionIdentifier, actionTitle, completionHandler) in
    let url:NSURL = NSURL(string: customParameters["deeplinking-path"] as! String)!
    self.router?.handleURL(url, withCompletion: nil)
FollowAnalytics.start(with: configuration, startupOptions: launchOptions)

Interactive notifications

What are interactive notifications

FollowAnalytics SDK enables you to integrate features to your push notifications that allows the user to use the notification without needing to access the app (this could be used add share on social media or feedback). These are called interactive notifications.

Previously, to ensure your interactive notification categories were properly set, you had to write your category definition code inside the followAppsRegisterNotificationCategories delegate method, so that the SDK can trigger this registration when needed.

From 6.0 on, given that notification registration and notification display authorization are two different processes, FollowAnalytics handles only the notification registration. Is your responsibility to request proper notification center authorization including notification categories. For those who don't need interactive notification and don't want to handle authorization we do provide a method requestNotificationCenterDefaultAuthorisation that can be called on FollowAnalytics class.

Once set up the categories can be used when creating a FollowAnalytics push campaign.

If a user receives an interactive notification sent from FollowAnalytics, and taps one of the buttons, the SDK calls the onIncomingCustomCampaign handler, if defined on FollowAnalyticsConfiguration object before startup, and passes the action identifier and title. If no custom parameter were defined when creating the campaign, the first parameter is an empty dictionary.

Custom handling of rich campaigns

What are Rich Campaigns?

Among the layouts available on the FollowAnalytics platform, you can choose "Custom web page" and "templates". These layouts are called Rich Campaigns. Our SDK provides a default display for Rich campaigns, but you can replace them with your one of your own.

Rich Campaigns can be handled directly by the app code. If you do not want the code to handle the message automatically, and would rather show the message yourself when you see fit, you can turn on the switch labelled "automatically display content" in the Advanced Options when creating the campaign.

For campaigns where the content is not handled by FollowAnalytics, set your handler to onIncomingCustomCampaign on the FAFollowAnalyticsConfiguration before the SDK startup.

Pausing and resuming in-app campaigns

What is pausing and resuming an in-app campaign?

Pausing campaigns are used to prevent in-app from being displayed on certain screens and views of your app. You may pause a screen of the app when it is too important, or is part of a process that is too important to be interrupted by an in-app (i.e a payment screen in the process of the user making a purchase).

When the screen is safe to display an in-app, you resume in-app campaigns. Any campaign supposed to be displayed when the mechanism is paused, is stacked and shown as soon as the mechanism is resumed. This way you can send send in-app campaigns without impacting the user experience.

To pause and resume campaigns, add the following methods in you code at the location you wish the pause and resume to take effect:


[FollowAnalytics.inApp pauseCampaignDisplay]
[FollowAnalytics.inApp resumeCampaignDisplay]



Create safe spaces for you in-app messages

Rather than pause everywhere you have an important screen or process, you can pause right at the initialization of the SDK and resume in the areas you think it is safe for in-app campaigns to be displayed.

Enable campaign archiving

FollowAnalytics SDK allows you to store all campaigns and push notifications received by your app . This makes them available for custom usage, like building an inbox. All scheduled campaigns received by a device can be archived locally and accessed from the developer's code, formatted as a message object. In order to configure your campaign storage, you have to set on your FollowAnalyticsConfiguration object, before the sdk startup the following properties:


@property(nonatomic, readonly, assign) BOOL archivePushMessages;
@property(nonatomic, readonly, assign) BOOL archiveInAppMessages;


open var archivePushMessages: Bool { get }
open var archiveInAppMessages: Bool { get }

In the FollowAnalyticsInApp and FollowAnalyticsPush protocols you will find all methods related to a simple database. They are implemented by FollowAnalytics.inApp and FollowAnalytics.push

⚠️ If you use this feature (storeMessages), we won't delete any message.

Data Wallet

What is the Data Wallet?

The Data Wallet is a consent management and data declaration tool that helps you on your way to in compliance with GDPR.

Your Data Wallet puts together what is called a policy. This policy which is created from the FollowAnalytics platform, is what brings together the legal texts, data categories, recipients and purposes you have determined in your Data Wallet. There could only be one policy at a time. Every time it is updated on the platform, the policy downloaded by the SDK.

All the data in the SDK will be in a JSON format and the developer will need to reorganize them in order to display them. The use of this feature is one of the most advanced for FollowAnalytics. We recommend that the developer working with the Data Wallet should be familiar with the FollowAnalytics and that most features were already installed.

If you want to use Data Wallet, the very first step is to enable it in your app at startup. This is done by accessing the FollowAnalyticsConfiguration object which contains the property isDataWalletEnabled. Set this property to true.

Now that the Data Wallet is enabled, the SDK will automatically download the new policies as they are published. In order to deal with the currently known policy, call the following APIs:

// gets the current policy
id<FADataWalletPolicy> policy = [FollowAnalytics.dataWallet getPolicy];
// true if the current policy is considered accepted
BOOL policyIsRead =  FollowAnalytics.dataWallet.isRead;
// informs the SDK that the user has accepted the current policy
[FollowAnalytics.dataWallet setIsRead:true];

There could only be one active policy at a time. When a new policy becomes available online, the SDK will call on the main thread onDataWalletPolicyChange, callback set on the FollowAnalyticsConfiguration. To set this up before starting the SDK, include the following code:

FollowAnalyticsConfiguration* configuration = [FollowAnalyticsConfiguration configurationWith:^(FollowAnalyticsMutableConfiguration * _Nonnull c) {
    c.isDataWalletEnabled = true;
    c.onDataWalletPolicyChange = ^{
      [self displayNewPolicy];

At each major policy update, there needs to be consent from the client. When the user accepts a policy call [FollowAnalytics.dataWallet setIsRead:true] to mark the current policy as "read". In other words:

The SDK records the major version of the current policy for future reference. By default, if no other configuration is present, the SDK will return a default policy with version 0.0. This policy is always read. You should check for version 0.0 and handle it appropriately.

Custom default policy

If you want to provide a custom default policy for your users, download the policy JSON file from the back office and add it to your app, then modify the configuration to use it as follows:

FollowAnalyticsConfiguration* configuration = [FollowAnalyticsConfiguration configurationWith:^(FollowAnalyticsMutableConfiguration * _Nonnull c) {
    // assuming that you have Policy.json in you main bundle
    c.dataWalletDefaultPolicyPath = [[NSBundle mainBundle] pathForResource:@"Policy" ofType:@"json"];

Advanced Use Cases

Configure the SDK

Before initializing the SDK you must enable the different functions of the SDK.

Parameter Type Default Value Description
apiKey string - Your app api key to use our SDK
appGroup string - An app group identifier to manage badges
isVerbose boolean false To avoid sending irrelevant logs to the production server (debug in previous versions)
apiMode enum .prod Either .dev or .prod for Swift and FollowAnalyticsAPIModeDev or FollowAnalyticsAPIModeProd for objective C
environment string - If you want to use a custom environment
environmentDomain string If you want to use a custom domain
environmentProtocol string https By default we use https, you can change it to http
optInAnalyticsDefault boolean true To choose your default opt-in / opt-out behavior
crashReportingEnabled boolean true To enable the crash reports
isDataWalletEnabled boolean false To enable or disable the DataWallet
dataWalletDefaultPolicyPath string - To determine the path of your dataWallet policy
onDataWalletPolicyChange call back - Called when a new significant version of dataWallet policy is available
archivePushMessages boolean false To choose if you want to archive push messages or not
archiveInAppMessages boolean false To choose if you want to archive inApp messages or not
maxBackgroundTimeWithinSession int 120 To determine the lifetime of a session when in background (between 15 and 3600)
onIncomingDeepLink call back - Called when the app is opened from a deep link
onOpenURL call back - Called when the user opens an url from your app
onIncomingCustomCampaign call back - Called when the SDK recive a custom campaign
onConsoleLog call back - Called when new logs are made internally in FollowAnalytics SDK

Manual installation of the SDK

Cocoapods is the preferred method

Even though you can install the SDK manually, cocoapods is the preferred method, since it will take care of much of the work and ensure your SDK is easily updated.

  1. Go to your Xcode project’s General settings of your target, drag and drop the FollowAnalytics.framework in the Embedded Binaries section. Make sure Copy items if needed is selected and click Finish.

  2. Create a new Run Script Phase in your app’s target’s Build Phases and paste the following snippet in the script text field:

    bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/FollowAnalytics.framework/"

    This step is required to work around an App Store submission bug when archiving universal binaries.

  3. Now, you can proceed to configuring and validating your setup.

Manual installation of Rich Push notifications

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

    • UserNotifications.framework
    • MobileCoreServices.framework
  3. Select the target of your main app, in Build phase

    1. Press the + button, and select New Copy File Phase.
    2. Change the destination to Frameworks
    3. Add the FANotificationService.framework
  4. Create a new Run Script Phase in your app’s target’s Build Phases and paste the following snippet in the script text field:

    bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/FANotificationExtension.framework/"

    This step is required to work around an App Store submission bug when archiving universal binaries.

InApp Template Configuration

In your info.plist add the following line (only required for fullScreen InApp): View controller-based status bar appearance and set the boolean to NO

Handling URLs in your application

Apple introduced App Transport Security (ATS) in iOS 9 to improve user security and privacy by requiring apps to use secure network connections over HTTPS. At WWDC 2016 they announced that apps submitted to the App Store will be required to support ATS at the end of the year. To give you additional time to prepare, this deadline was extended. Apple has yet to announce the new date. Learn more about it here.

While this security policy is not enforced you can load unsafe urls by adding the following exception to your .plist.


When creating campaigns in FollowAnalytics, you will be able to use URLs for message contents or actions. We recommend using HTTPS, but if you cannot, you will need to add this exception in your .plist file.

Migrating from older versions

Migrating from 6.1 to 6.2

Migrating to 6.0 and higher

Migrating from 5.3 to 5.4

Migrating from 5.2 to 5.3

Migrating from 5.0 to 5.1

Migrating from 4 to 5.0.0

To use version 5.0.0+ of the iOS SDK:

Migrating from 3.* to 4.*

The migration is seamless. However, please refer to the section around user attributes to learn how to feed user profiles using the SDK.

Migrating from 2.* to 3.0.0

To use version 3.0.0+ of the iOS SDK:

Nothing else changes. Please refer to the rest of the documentation to discover what the newer versions of the SDK now allow.