Documentation > iOS

Getting Started

Install the Framework

The CleverTap SDK is distributed via CocoaPods and as a manually installable framework in your project. You may choose any method that fits your workflow. Both methods are documented below

Option A – Install using CocoaPods (recommended)

To add CleverTap to your project, add the SDK to your Podfile as shown below.

pod "CleverTap-iOS-SDK"
copy Copied

You can also install SDK build variants to capture custom events in App Extensions and watchOS apps. See example Project and Podfile.

Once you have updated your Podfile run pod install to automatically download and install the SDK in your project.

Upgrading the CleverTap SDK?

  • Run pod update CleverTap-iOS-SDK in your project directory.

Option B – Install Manually

Additionally, you are required to add the following frameworks to your Xcode project

SystemConfiguration
CoreTelephony
Security
UIKit
copy Copied

You can also manually add SDK build variants to capture custom events in App Extensions and watchOS apps. See our Github repo for more details.

– Starting with v3.0.0, the Framework supports iOS versions 8 and above, prior versions support iOS versions 7 and above
– CleverTap iOS SDK size: When you build a library in iOS, you must include a build for every architecture supported by iOS. This leads to a perceived large file size. However, at app compilation time Xcode will only build in the required architecture, leading to a vastly smaller compiled file size. The size overhead is only about 150 KB per target after compilation

Add CleverTap Credentials

With the SDK added to your project, update your Info.plist file
with the below listed key/value pairs

  1. Create a key called CleverTapAccountID with a string value
  2. Create a key called CleverTapToken with a string value
  3. Insert the Account ID and Account Token values from your CleverTap Account. These values are found under Settings → Settings Dashboard → Account ID and Token, in the dashboard

CleverTap credentials in your Info.plist

Be sure to add the above account credentials to the plist for each target in which you are including the SDK.

If you’d rather set your account credentials in code, see here.

Installation steps for Swift

For a project written in Swift, you are required to follow the below mentioned steps in addition to the Framework installation steps mentioned above.

  1. Add the example bridging-header.h (rename to YOUR-PROJECT-NAME-Bridging-Header.h, if you like) to your project.
  2. Add the path to that bridging-header.h in the Objective-C Bridging Header section of your project Build Settings.

Alternatively, you can also append the contents of the bridging-header.h to your existing Bridging Header file.

For a Swift App Extension, the bridging-header would look like this. And, in a watchOS Host app, it would look like this.

SDK Integration

With the SDK installed and initialized in your project,
add the CleverTap.h to your AppDelegate and every class where you’d like to record user events

#import <CleverTapSDK/CleverTap.h>
copy Copied

Option A – Automatic Integration

The SDK can be automatically integrated in your application by calling [CleverTap autoIntegrate] (typically in application:didFinishLaunchingWithOptions:)

This will automatically notify the SDK that your app has launched, push notifications, in-app notifications and deep link tracking, and set up a singleton instance of the CleverTap class

Automatic integration is accomplished by proxying the AppDelegate and “inserting” a CleverTap AppDelegate behind the AppDelegate. The proxy will first call the AppDelegate and then call the CleverTap AppDelegate

Select Platform
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    ...
    [CleverTap autoIntegrate];
    ...
}
copy Copied
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject:AnyObject]?) -> Bool {
    ...
    CleverTap.autoIntegrate()
    ...
}
copy Copied

Note: automatic integration is inapplicable inside App Extensions and watchOS apps. For examples on how to record custom events inside your App Extensions see here and from watchOS apps see here and here.

Option B – Manual Integration

If you choose to manually integrate the SDK, follow these steps

Manually integrate push notification support

CleverTap using the SDK is capable of sending push notifications to your users using the dashboard. To enable this support, when your app delegate receives the application:didRegisterForRemoteNotificationsWithDeviceToken: message, include a call to CleverTap setPushToken: as follows:

Select Platform
- (void) application:(UIApplication *)application
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
      [[CleverTap sharedInstance] setPushToken:deviceToken];
}
copy Copied
func application(application: UIApplication,
                 didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
    CleverTap.sharedInstance()?.setPushToken(deviceToken)
}
copy Copied

The above will save the user’s APNS token with CleverTap. This token is used to send push notifications.

Next, include a call to handleNotificationWithData: when your app delegate is sent the messages:

application:didReceiveRemoteNotification:
application:didReceiveLocalNotification:
application:didReceiveRemoteNotification:fetchCompletionHandler:
application:handleActionWithIdentifier:forRemoteNotification:completionHandler:
application:handleActionWithIdentifier:forLocalNotification:completionHandler:
copy Copied

as follows:

Select Platform
- (void) application:(UIApplication *)application
    didReceiveRemoteNotification:(NSDictionary *)userInfo {
      [[CleverTap sharedInstance] handleNotificationWithData:userInfo];
    }
- (void) application:(UIApplication *)application
    didReceiveLocalNotification:(UILocalNotification *)notification {
      [[CleverTap sharedInstance] handleNotificationWithData:notification];
    }
    
// As of iOS 8 and above
- (void) application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier
    forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler {
        [[CleverTap sharedInstance] handleNotificationWithData:notification];
        if (completionHandler) completionHandler();
    }
    
- (void) application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier
    forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler {
        [[CleverTap sharedInstance] handleNotificationWithData:userInfo];
        if (completionHandler) completionHandler();
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo 
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
	[[CleverTap sharedInstance] handleNotificationWithData:userInfo];
    completionHandler(UIBackgroundFetchResultNoData);
}
copy Copied
func application(application: UIApplication, didReceiveRemoteNotification
    userInfo: [NSObject : AnyObject]) {
    CleverTap.sharedInstance()?.handleNotificationWithData(userInfo)
}

func application(application: UIApplication, didReceiveLocalNotification
    notification: UILocalNotification) {
    CleverTap.sharedInstance()?.handleNotificationWithData(notification)
}

// As of iOS 8 and above
func application(application: UIApplication, handleActionWithIdentifier identifier: String?,
                 forLocalNotification notification: UILocalNotification, completionHandler: () -> Void) {
    CleverTap.sharedInstance()?.handleNotificationWithData(notification)
    completionHandler()
}

func application(application: UIApplication, handleActionWithIdentifier identifier: String?,
                 forRemoteNotification userInfo: [NSObject : AnyObject], completionHandler: () -> Void) {
    CleverTap.sharedInstance()?.handleNotificationWithData(userInfo)
    completionHandler()
}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], 
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
	CleverTap.sharedInstance()?.handleNotification(withData: userInfo)
    completionHandler(.noData)
}
copy Copied

Note: not applicable inside App Extensions and watchOS apps.

iOS 10 has introduced the UNUserNotificationCenterDelegate for handling notifications. Implementation is optional, but if you do implement the Delegate, please note that, whether or not you have used automatic integration, if you wish CleverTap to track notification opens and fire attached deep links, you must manually call the SDK as follows:

Select Platform
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
         withCompletionHandler:(void (^)())completionHandler {
    
    /**
     Use this method to perform the tasks associated with your app’s custom actions. When the user responds to a notification, the system calls this method with the results. You use this method to perform the task associated with that action, if at all. At the end of your implementation, you must call the completionHandler block to let the system know that you are done processing the notification.
     
     You specify your app’s notification types and custom actions using UNNotificationCategory and UNNotificationAction objects. You create these objects at initialization time and register them with the user notification center. Even if you register custom actions, the action in the response parameter might indicate that the user dismissed the notification without performing any of your actions.
     
     If you do not implement this method, your app never responds to custom actions.
     
     see https://developer.apple.com/reference/usernotifications/unusernotificationcenterdelegate/1649501-usernotificationcenter?language=objc
     
    **/
    
    // if you wish CleverTap to record the notification open and fire any deep links contained in the payload
    [[CleverTap sharedInstance] handleNotificationWithData:response.notification.request.content.userInfo];
    
    completionHandler();
}
copy Copied
func userNotificationCenter(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse,
                                withCompletionHandler completionHandler: @escaping () -> Void) {
        
	/**
	 Use this method to perform the tasks associated with your app’s custom actions. When the user responds to a notification, the system calls this method with the results. You use this method to perform the task associated with that action, if at all. At the end of your implementation, you must call the completionHandler block to let the system know that you are done processing the notification.
	 
	 You specify your app’s notification types and custom actions using UNNotificationCategory and UNNotificationAction objects. You create these objects at initialization time and register them with the user notification center. Even if you register custom actions, the action in the response parameter might indicate that the user dismissed the notification without performing any of your actions.
	 
	 If you do not implement this method, your app never responds to custom actions.
	 
	 see https://developer.apple.com/reference/usernotifications/unusernotificationcenterdelegate/1649501-usernotificationcenter
	 
	 **/
	
	// if you wish CleverTap to record the notification open and fire any deep links contained in the payload
	CleverTap.sharedInstance().handleNotification(withData: response.notification.request.content.userInfo)
	
	completionHandler()
        
}
copy Copied

In-App Notification Support

The CleverTap SDK allows you to show In-App notifications to your users. You can design in-app notifications right from the dashboard, without writing a single line of code. There is no code required for this feature

Note: not applicable inside App Extensions and watchOS apps.

Manually enable support for Universal (Deep) Link Tracking

Deep links are a way of launching a native app and providing additional information telling it do some specific event or show specific content. CleverTap automatically tracks universal links that open your application. If you have universal (deep) links coming to your app, you can capture the incoming UTM parameters easily. Call handleOpenURL:sourceApplication: when the application:openURL:sourceApplication:annotation: message is sent to your app delegate:

Select Platform
- (BOOL) application:(UIApplication *)application
    openURL:(NSURL *)url
    sourceApplication:(NSString *)sourceApplication
    annotation:(id)annotation {
      [[CleverTap sharedInstance] handleOpenURL:url sourceApplication:sourceApplication];
      return YES;
}

- (BOOL)application:(UIApplication *)app
            openURL:(NSURL *)url
            options:(NSDictionary *)options {
    [[CleverTap sharedInstance] handleOpenURL:url sourceApplication:nil];
    return YES;
}

- (void)openURL:(NSURL*)url options:(NSDictionary<NSString *, id> *)options
completionHandler:(void (^ __nullable)(BOOL success))completion {
    [[CleverTap sharedInstance] handleOpenURL:url sourceApplication:nil];
    if (completion) {
        completion(YES);
    }
}
copy Copied
func application(application: UIApplication, openURL url: NSURL,
                 sourceApplication: String?, annotation: AnyObject) -> Bool {
    CleverTap.sharedInstance()?.handleOpenURL(url, sourceApplication: sourceApplication)
    return true
}

// Swift 3
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
   CleverTap.sharedInstance()?.handleOpen(url, sourceApplication: nil)
   return true
}

func open(_ url: URL, options: [String : Any] = [:],
                   completionHandler completion: ((Bool) -> Swift.Void)? = nil) {
	CleverTap.sharedInstance()?.handleOpen(url, sourceApplication: nil)
	completion?(false)
}
copy Copied

Note: not applicable inside App Extensions and watchOS apps.

Providing Location information to CleverTap

If your application is collecting location information you can pass it to CleverTap for, among other things, more fine-grained geo-targeting and segmentation purposes. When you have location information call:

Select Platform
- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
           fromLocation:(CLLocation *)oldLocation {
    [CleverTap setLocation: newLocation.coordinate];
}
copy Copied
func locationManager(manager: CLLocationManager, didUpdateToLocation newLocation: CLLocation,
                     fromLocation oldLocation: CLLocation) {
    CleverTap.setLocation(newLocation.coordinate)
}
copy Copied

Intro to User Profiles

CleverTap stores the user’s demographic data (gender, age, location), app and website interaction events, campaign visits and transaction history to give you a complete picture for every user.

A User Profile is automatically created for every user launching your mobile application – whether logged in or not.

Initially, the User Profile starts out as “Anonymous” – which means that the profile does not yet contain any identifiable information about the user. You can choose to enrich the profile with attributes like name, age, customer id, etc.

CleverTap provides pre-defined profile properties such as name, phone, gender, age etc to represent well know properties associated with a profile. It is strongly recommended to use these standard property names. A list of all pre-defined property names is available here. In addition, we also support arbitrary single and multi value profile properties.

Examples of updating profile properties for a project written in Objective-C are documented below:

Select Platform
// each of the below mentioned fields are optional
// if set, these populate demographic information in the Dashboard
NSDateComponents *dob = [[NSDateComponents alloc] init];
dob.day = 24;
dob.month = 5;
dob.year = 1992;
NSDate *d = [[NSCalendar currentCalendar] dateFromComponents:dob];
NSDictionary *profile = @{
    @"Name": @"Jack Montana",               // String
    @"Identity": @61026032,                 // String or number
    @"Email": @"jack@gmail.com",            // Email address of the user
    @"Phone": @"+14155551234",              // Phone (with the country code, starting with +)
    @"Gender": @"M",                        // Can be either M or F
    @"Employed": @"Y",                      // Can be either Y or N
    @"Education": @"Graduate",              // Can be either Graduate, College or School
    @"Married": @"Y",                       // Can be either Y or N
    @"DOB": d,                              // Date of Birth. An NSDate object
    @"Age": @28,                            // Not required if DOB is set
    @"Photo": @"www.foobar.com/image.jpeg", // URL to the Image

// optional fields. controls whether the user will be sent email, push etc.
    @"MSG-email": @NO,                      // Disable email notifications
    @"MSG-push": @YES,                      // Enable push notifications
    @"MSG-sms": @NO                         // Disable SMS notifications
};

[[CleverTap sharedInstance] profilePush:profile];
copy Copied
NSDictionary *profile = @{
    @"Customer Type": @"Silver",
    @"Prefered Language": @"English",
};

[[CleverTap sharedInstance] profilePush:profile];

/**
 * Data types:
 * The value of a property can be of type NSDate, a NSNumber, a NSString, or a BOOL.
 */
copy Copied
// To set a multi-value property
[[CleverTap sharedInstance] profileSetMultiValues:@[@"bag", @"shoes"] forKey:@"myStuff"];

// To add an additional value(s) to a multi-value property
[[CleverTap sharedInstance] profileAddMultiValue:@"coat" forKey:@"myStuff"];
// or
[[CleverTap sharedInstance] profileAddMultiValues:@[@"socks", @"scarf"] forKey:@"myStuff"];

//To remove a value(s) from a multi-value property
[[CleverTap sharedInstance] profileRemoveMultiValue:@"bag" forKey:@"myStuff"];
[[CleverTap sharedInstance] profileRemoveMultiValues:@[@"shoes", @"coat"] forKey:@"myStuff"];

//To remove the value of a property (scalar or multi-value)
[[CleverTap sharedInstance] profileRemoveValueForKey:@"myStuff"];
copy Copied

Examples of updating profile properties for a project written in Swift are documented below:

Select Platform
// each of the below mentioned fields are optional
// if set, these populate demographic information in the Dashboard
let dob = NSDateComponents()
dob.day = 24
dob.month = 5
dob.year = 1992
let d = NSCalendar.currentCalendar().dateFromComponents(dob)
let profile: Dictionary<String, AnyObject> = [
    "Name": "Jack Montana",                 // String
    "Identity": 61026032,                   // String or number
    "Email": "jack@gmail.com",              // Email address of the user
    "Phone": "+14155551234",                // Phone (with the country code, starting with +)
    "Gender": "M",                          // Can be either M or F
    "Employed": "Y",                        // Can be either Y or N
    "Education": "Graduate",                // Can be either School, College or Graduate
    "Married": "Y",                         // Can be either Y or N
    "DOB": d!,                              // Date of Birth. An NSDate object
    "Age": 28,                              // Not required if DOB is set
    "Photo": "www.foobar.com/image.jpeg",   // URL to the Image

// optional fields. controls whether the user will be sent email, push etc.
    "MSG-email": false,                     // Disable email notifications
    "MSG-push": true,                       // Enable push notifications
    "MSG-sms": false                        // Disable SMS notifications
]

CleverTap.sharedInstance()?.profilePush(profile)
copy Copied
let profile: Dictionary<String, AnyObject> = [
    "Customer Type": "Silver",
    "Prefered Language": "English"
]

CleverTap.sharedInstance()?.profilePush(profile)

/**
 * Data types:
 * The value of a property can be of type NSDate, a Number, a String, or a Bool.
 */
copy Copied
// To set a multi-value property
CleverTap.sharedInstance()?.profileSetMultiValues(["bag", "shoes"], forKey: "myStuff")

// To add an additional value(s) to a multi-value property
CleverTap.sharedInstance()?.profileAddMultiValue("coat", forKey: "myStuff")
// or
CleverTap.sharedInstance()?.profileAddMultiValues(["socks", "scarf"], forKey: "myStuff")

//To remove a value(s) from a multi-value property
CleverTap.sharedInstance()?.profileRemoveMultiValue("bag", forKey: "myStuff")
CleverTap.sharedInstance()?.profileRemoveMultiValues(["shoes", "coat"], forKey: "myStuff")

//To remove the value of a property (scalar or multi-value)
CleverTap.sharedInstance()?.profileRemoveValueForKey("myStuff")
copy Copied

CleverTap provides easy ways to enrich the user profile with data from sources like Facebook or Google Plus. You can also store custom attributes in a user profile. These attributes can later be used to segment users.

For complete User Profile documentation, see: Working with User Profiles

Intro to User Events

A User Event is an event that a user takes in your mobile application. CleverTap records the event on the User Profile, using an Event Name and optional associated key:value-based Event Properties. You can then segment users, target and personalize messaging based on both the Event Name and specific Event Properties.

An example of recording a User Event called Product Viewed:

Select Platform
// event without properties
[[CleverTap sharedInstance] recordEvent:@"Product viewed"];
copy Copied
// event without properties
CleverTap.sharedInstance()?.recordEvent("Product viewed")
copy Copied

An example of recording a User Event called Product Viewed with Properties:

Select Platform
// event with properties
NSDictionary *props = @{
    @"Product name": @"Casio Chronograph Watch",
    @"Category": @"Mens Accessories",
    @"Price": @59.99,
    @"Date": [NSDate date]
};

[[CleverTap sharedInstance] recordEvent:@"Product viewed" withProps:props];

/**
 * Data types:
 * The value of a property can be of type NSDate, a NSNumber, a NSString, or a BOOL.
 *
 * NSDate object:
 * When a property value is of type NSDate, the date and time are both recorded to the second.
 * This can be later used for targeting scenarios.
 * For e.g. if you are recording the time of the flight as an event property,
 * you can send a message to the user just before their flight takes off.
 */
copy Copied
// event with properties
let props = [
    "Product name": "Casio Chronograph Watch",
    "Category": "Mens Accessories",
    "Price": 59.99,
    "Date": NSDate()
]

CleverTap.sharedInstance()?.recordEvent("Product viewed", withProps: props)

/**
 * Data types:
 * The value of a property can be of type NSDate, a Number, a String, or a Bool.
 *
 * NSDate object:
 * When a property value is of type NSDate, the date and time are both recorded to the second.
 * This can be later used for targeting scenarios.
 * For e.g. if you are recording the time of the flight as an event property,
 * you can send a message to the user just before their flight takes off.
 */
copy Copied

For an example of how to record a custom event from a watchOS app, see here and here.

For an example of recording an event from an App Extension, see here.

Events help you understand how your users interact with your app. CleverTap tracks certain common User Events automatically, while giving you the flexibility to record business specific events.

For a complete guide to recording User Events, see: Working with User Events

Debugging

During development, we recommend that you set the SDK to debug mode, in order to log warnings or other important messages to the iOS logging system. This can be done by setting the debug level to 1:

Select Platform
#ifdef DEBUG
[CleverTap setDebugLevel:1];
#endif
copy Copied
CleverTap.setDebugLevel(1)
copy Copied

To turn off debugging, set the debug level to 0 (default).