tvOS

Getting started

1. Install the SDK

The fastest and easiest way to use Localytics in your project is with CocoaPods. If you cannot use CocoaPods, use the alternative installation approach.

  1. Install CocoaPods by executing
    gem install cocoapods
    
  2. If you don't already have a Podfile in your Xcode project directory, create one with the following command
    pod init
    
  3. In your Podfile add the following content
    platform :tvos, '9.0'
    pod 'Localytics-tvOS', '~> 1.0'
    
  4. Install the Localytics SDK by executing the following in your Xcode project directory
    pod install
    
  5. Open the project workspace file (YOUR-PROJECT-NAME.xcworkspace) instead of the project file (YOUR-PROJECT-NAME.xcodeproj) to ensure that the Localytics dependency is properly loaded.

2. Initialize the SDK

In order to run the Localytics SDK, you must initialze the SDK using your Localytics app key. You can find your app key in the Localytics Dashboard.

If you have an app with extensive, engaged usage in the background, or you require more fine control over the session lifecycle (most apps don't), use the alternative session management approach.

In your application's delegate file:

  1. Import the Localytics SDK under any existing imports.

    Objective-C Swift

    @import Localytics;
    
    import Localytics
    
  2. Add the following line to the start of didFinishLaunchingWithOptions:.

    Objective-C Swift

    [Localytics autoIntegrate:@"YOUR-LOCALYTICS-APP-KEY" launchOptions:launchOptions];
    
    Localytics.autoIntegrate("YOUR-LOCALYTICS-APP-KEY", launchOptions: launchOptions)
    
  3. Compile and run your app.

More information on using the Localytics SDK within a Swift project is available here.

3. Next steps

Congratulations! You have successfully performed the basic Localytics integration and are now sending session data to Localytics. You have everything you need to track where your most highly engaged users are coming from.

Note that it may take a few minutes for your first datapoints to show up within the Localytics Dashboard. In the meantime, we suggest reading the next few sections to learn how to:

  1. Track one user action as an event
  2. Track one user property as a profile attribute

We recommend doing these things before releasing your app for the first time with Localytics.

Session lifecycle

With just the basic setup above, the Localytics SDK automatically tracks user engagement and retention by tracking patterns of foregrounding and backgrounding of your app. Upon foregrounding, the Localytics SDK automatically creates and uploads a "start session" datapoint that captures many details about the user's device (e.g., device model, OS version, device IDs) and is used for powering charts within Localytics.

Upon backgrounding, the SDK marks the current time. When the user returns to the app later and it has been more than 15 seconds since the user had last backgrounded the app, the SDK will close the previous session by creating a "close session" datapoint, create a new "start session" datapoint, and upload both of these datapoints. If the user foregrounds the app within 15 seconds of the previous backgrounding, the previous session is resumed as if the user had not left the app at all. Due to this automatic session lifecycle tracking, Localytics is able to derive session length, session interval, session counts, session trending, and a number of other core metrics for exploration in the Localytics Dashboard.

Whenever the app transitions to the foreground or background, the Localytics SDK attempts to upload any datapoints which are cached on the device. Uploads are performed in batches to reduce network use and increase the likelihood of successful uploads. Data remains on the device until it is successfully uploaded, and only then does the SDK remove it from the device.

Tagging events

Track user actions in your app using events in Localytics. All events must have a name, but you can also track the details of the action with event attributes. Event attributes help to provide context about why and how the action occurred. Every event can have up to 50 attributes unique to that event with each attribute having a limit of 255 characters.

Standard events

Standard events make it easier to analyze user behavior and optimize your app marketing around common business goals such as driving user registrations or purchases. You can also tag custom events for other user behavior in your app that doesn't match one of the standard events.

Purchased

Objective-C Swift

[Localytics tagPurchased:@"Shirt"
                  itemId:@"sku-123"
                itemType:@"Apparel"
               itemPrice:@15
              attributes:extraAttributes];
Localytics.tagPurchased("Shirt", itemId: "sku-123", itemType: "Apparel", itemPrice: 15, attributes: extraAttributes)

Added to Cart

Objective-C Swift

[Localytics tagAddedToCart:@"Shirt"
                    itemId:@"sku-123"
                  itemType:@"Apparel"
                 itemPrice:@15
                attributes:extraAttributes];
Localytics.tagAddedToCart("Shirt", itemId: "sku-123", itemType: "Apparel", itemPrice: 15, attributes: extraAttributes)

Started Checkout

Objective-C Swift

[Localytics tagStartedCheckout:@50
                     itemCount:@2
                    attributes:extraAttributes];
Localytics.tagStartedCheckout(50, itemCount: 2, attributes: extraAttributes)

Completed Checkout

Objective-C Swift

[Localytics tagCompletedCheckout:@50
                       itemCount:@2
                      attributes:extraAttributes];
Localytics.tagCompletedCheckout(50, itemCount: 2, attributes: extraAttributes)

Content Viewed

Objective-C Swift

[Localytics tagContentViewed:@"Top 10"
                   contentId:@"e8z7319zbe"
                 contentType:@"Article"
                  attributes:extraAttributes];
Localytics.tagContentViewed("Top 10", contentId: "e8z7319zbe", contentType: "Article", attributes: extraAttributes)

Searched

Objective-C Swift

[Localytics tagSearched:@"Celtics"
            contentType:@"Sports"
            resultCount:@15
             attributes:extraAttributes];
Localytics.tagSearched("Celtics", contentType: "Sports", resultCount: 15, attributes: extraAttributes)

Shared

Objective-C Swift

[Localytics tagShared:@"Top 10"
            contentId:@"e8z7319zbe"
          contentType:@"Article"
           methodName:@"Twitter"
           attributes:extraAttributes];
Localytics.tagShared("Top 10", contentId: "e8z7319zbe", contentType: "Article", methodName: "Twitter", attributes: extraAttributes)

Content Rated

Objective-C Swift

[Localytics tagContentRated:@"Headlines"
                  contentId:@"8a4z5j9q"
                contentType:@"Song"
                     rating:@5
                 attributes:extraAttributes];
Localytics.tagContentRated("Headlines", contentId: "8a4z5j9q", contentType: "Song", rating: 5, attributes: extraAttributes)

Customer Registered

The LLCustomer parameter is optional - you can pass in nil. However, if you do choose to include an LLCustomer object, the appropriate identifying users properties will be automatically set.

Objective-C Swift

[Localytics tagCustomerRegistered:[LLCustomer customerWithBlock:^(LLCustomerBuilder *builder) {
          builder.customerId = @"3neRKTxbNWYKM4NJ";
          builder.firstName = @"John";
          builder.lastName = @"Smith";
          builder.fullName = @"Mr. John Smith, III";
          builder.emailAddress = @"john@smith.com";
      }]
                       methodName:@"Facebook"
                       attributes:extraAttributes];
Localytics.tagCustomerRegistered((LLCustomer { (builder) in
  builder.customerId = "3neRKTxbNWYKM4NJ"
  builder.firstName = "John"
  builder.lastName = "Smith"
  builder.fullName = "Mr. John Smith, III"
  builder.emailAddress = "john@smith.com"
}), methodName: "Facebook", attributes: extraAttributes)

Customer Logged In

The LLCustomer parameter is optional - you can pass in nil. However, if you do choose to include an LLCustomer object, the appropriate identifying users properties will be automatically set.

Objective-C Swift

[Localytics tagCustomerLoggedIn:[LLCustomer customerWithBlock:^(LLCustomerBuilder *builder) {
          builder.customerId = @"3neRKTxbNWYKM4NJ";
          builder.firstName = @"John";
          builder.lastName = @"Smith";
          builder.fullName = @"Mr. John Smith, III";
          builder.emailAddress = @"john@smith.com";
      }]
                     methodName:@"Native"
                     attributes:extraAttributes];
Localytics.tagCustomerLoggedIn((LLCustomer { (builder) in
  builder.customerId = "3neRKTxbNWYKM4NJ"
  builder.firstName = "John"
  builder.lastName = "Smith"
  builder.fullName = "Mr. John Smith, III"
  builder.emailAddress = "john@smith.com"
}), methodName: "Native", attributes: extraAttributes)

Customer Logged Out

Objective-C Swift

[Localytics tagCustomerLoggedOut:extraAttributes];
Localytics.tagCustomerLoggedOut(extraAttributes)

Invited

Objective-C Swift

[Localytics tagInvited:@"SMS"
            attributes:extraAttributes];
Localytics.tagInvited("SMS", attributes: extraAttributes)

Custom event

Objective-C Swift

[Localytics tagEvent:@"Team Favorited"];
Localytics.tagEvent("Team Favorited")

Custom event with attributes

Objective-C Swift

[Localytics tagEvent:@"Team Favorited"
          attributes:@{@"Team Name" : @"Celtics", @"City" : @"Boston"}];
Localytics.tagEvent("Team Favorited", attributes: ["Team Name" : "Celtics", "City" : "Boston"])

Identifying users

The Localytics SDK automatically captures and uploads device IDs which the Localytics backend uses to uniquely identify users. Some apps connect to their own backend systems that use different IDs for uniquely identifying users. There is often additional identifying information, such as name and email address, connected with the external IDs. Localytics provides various setters for passing this information to Localytics when it is available in your app. Using these setters ensures that you will be able to properly connect Localytics IDs to the IDs available in other systems.

To easily identify your users during your login and/or registration flow, use our customer registered and customer logged in standard events.

Customer ID

Objective-C Swift

[Localytics setCustomerId:@"3neRKTxbNWYKM4NJ"];
Localytics.setCustomerId("3neRKTxbNWYKM4NJ")

Customer first name

Objective-C Swift

[Localytics setCustomerFirstName:@"John"];
Localytics.setCustomerFirstName("John")

Customer last name

Objective-C Swift

[Localytics setCustomerLastName:@"Smith"];
Localytics.setCustomerLastName("Smith")

Customer full name

Objective-C Swift

[Localytics setCustomerFullName:@"Sir John Smith, III"];
Localytics.setCustomerFullName("Sir John Smith, III")

Customer email address

Objective-C Swift

[Localytics setCustomerEmail:@"sir.john@smith.com"];
Localytics.setCustomerEmail("sir.john@smith.com")

User profiles

Track user properties using profile attributes in Localytics. Each profile has one or more named properties that describe that user. Because they contain rich user data, profiles are excellent for creating audiences to target with personalized messaging. Each profile is identified by a unique user ID that you provide to Localytics via the SDK. If you do not set a known user ID, then the Localytics SDK automatically generates an anonymous profile ID.

Each time you set the value of a profile attribute, you can set the scope to "app-level" or "org-level". App-level profile attributes are only stored in relation to that specific Localytics app key, so they can only be used for building audiences for that one app. Org-level profile attributes are available to all apps in the org, so they can be used across multiple Localytics app keys, which might represent the same app on a different platform or multiple apps produced by your company. If you choose not to set a scope, the SDK defaults to "app-level" scope.

If you repeatedly set the same profile attribute value, the Localytics SDK and backend will take care of deduplicating the values for you so only the most recent value gets stored for that profile.

Profile names must be NSStrings and cannot be nil, empty strings, or begin with an underscore ("_"). Property values must be either single instances or an NSArray of: NSString, NSNumber, or NSDate. Passing in nil or NSNull will delete the value.

Setting a profile attribute value

Numeric value

Objective-C Swift

[Localytics setValue:@45 forProfileAttribute:@"Age" withScope:LLProfileScopeOrganization];
Localytics.setValue(45, forProfileAttribute: "Age", with: .organization)

Numeric values in a set

Objective-C Swift

[Localytics setValue:@[@8, @13] forProfileAttribute:@"Lucky Numbers" withScope:LLProfileScopeApplication];
Localytics.setValue([8, 13], forProfileAttribute: "Lucky numbers", with: .application)

Date value

Objective-C Swift

[Localytics setValue:[NSDate date] forProfileAttribute:@"Last Purchase Date" withScope:LLProfileScopeOrganization];
Localytics.setValue(NSDate(), forProfileAttribute: "Last Purchase Date", with: .organization)

Date values in a set

Objective-C Swift

NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MM-dd-yyyy"];
[Localytics setValue:@[[dateFormatter dateFromString:@"10-01-2015"], [dateFormatter dateFromString:@"03-17-2016"]] forProfileAttribute:@"Upcoming Milestone Dates" withScope:LLProfileScopeApplication];
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy"
Localytics.setValue([dateFormatter.date(from: "10-01-2015")!, dateFormatter.date(from: "03-17-2016")!], forProfileAttribute: "Upcoming Milestone Dates", with: .application)

String value

Objective-C Swift

[Localytics setValue:@"New York, New York" forProfileAttribute:@"Hometown" withScope:LLProfileScopeOrganization];
Localytics.setValue("New York, New York", forProfileAttribute: "Hometown", with: .organization)

String values in a set

Objective-C Swift

[Localytics setValue:@[@"New York", @"California", @"South Dakota"] forProfileAttribute:@"States Visited" withScope:LLProfileScopeApplication];
Localytics.setValue(["New York", "California", "South Dakota"], forProfileAttribute: "States Visited", with: .application)

Removing a profile attribute

Objective-C Swift

[Localytics deleteProfileAttribute:@"Days Until Graduation" withScope:LLProfileScopeApplication];
Localytics.deleteProfileAttribute("Days Until Graduation", with: .application)

Adding to a set of profile attribute values

Adding a numeric value to a set

Objective-C Swift

[Localytics addValues:@[@8] toSetForProfileAttribute:@"Lucky Numbers" withScope:LLProfileScopeApplication];
Localytics.addValues([8], toSetForProfileAttribute: "Lucky Numbers", with: .application)

Adding a date value to a set

Objective-C Swift

NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MM-dd-yyyy"];
[Localytics addValues:@[[dateFormatter dateFromString:@"04-19-2015"], [dateFormatter dateFromString:@"12-24-2015"]] toSetForProfileAttribute:@"Upcoming Milestone Dates" withScope:LLProfileScopeApplication];
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy"
Localytics.addValues([dateFormatter.date(from: "4-19-2015")!, dateFormatter.date(from: "12-24-2015")!], toSetForProfileAttribute: "Upcoming Milestone Dates", with: .application)

Adding a string value to a set

Objective-C Swift

[Localytics addValues:@[@"North Dakota"] toSetForProfileAttribute:@"States Visited" withScope:LLProfileScopeApplication];
Localytics.addValues(["North Dakota"], toSetForProfileAttribute: "States Visited", with: .application)

Removing from a set of profile attribute values

Removing numeric values from a set

Objective-C Swift

[Localytics removeValues:@[@8, @9] fromSetForProfileAttribute:@"Lucky Numbers" withScope:LLProfileScopeApplication];
Localytics.removeValues([8, 9], fromSetForProfileAttribute: "Lucky Numbers", with: .application)

Removing date values from a set

Objective-C Swift

NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MM-dd-yyyy"];
[Localytics removeValues:@[[dateFormatter dateFromString:@"03-17-2016"]] fromSetForProfileAttribute:@"Upcoming Milestone Dates" withScope:LLProfileScopeApplication];
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy"
Localytics.removeValues([dateFormatter.date(from: "03-17-2016")!], fromSetForProfileAttribute: "Upcoming Milestone Dates", with: .application)

Removing string values from a set

Objective-C Swift

[Localytics removeValues:@[@"California"] fromSetForProfileAttribute:@"States Visited" withScope:LLProfileScopeApplication];
Localytics.removeValues(["California"], fromSetForProfileAttribute: "States Visited", with: .application)

Incrementing a numeric profile attribute value

Objective-C Swift

[Localytics incrementValueBy:1 forProfileAttribute:@"Age" withScope:LLProfileScopeOrganization];
Localytics.incrementValueBy(1, forProfileAttribute: "Age", with: .organization)

Decrementing a numeric profile attribute value

Objective-C Swift

[Localytics decrementValueBy:3 forProfileAttribute:@"Days Until Graduation" withScope:LLProfileScopeApplication];
Localytics.decrementValueBy(3, forProfileAttribute: "Days Until Graduation", with: .application)

Tracking user flow

Track screens or views within your app so you can visualize user flow within the Localytics Dashboard. We recommend exhaustively tagging every visible view in your app.

The Localytics SDK will perform duplicate suppression on two identical tagged screens that occur in a row within a single session. For example, in the set of screens {"Screen 1", "Screen 1"}, the second screen would be suppressed. However, in the set {"Screen 1", "Screen 2", "Screen 1"}, no duplicate suppression would occur.

Objective-C Swift

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [Localytics tagScreen:@"Item List"];
}
override func viewDidAppear(_ animated: Bool) {
  super.viewDidAppear(animated)
  Localytics.tagScreen("Item List")
}

Tracking revenue

There are two ways to think about Lifetime Value (LTV) in Localytics: monetary and non-monetary. If your app allows real currency transactions, our Dashboard can show LTV in USD. If your app uses virtual currencies like coins or tokens, you can configure your app to report LTV as the raw data you pass in.

You can configure each Mobile App in Localytics to have either a monetary value or raw data for Lifetime Value:

Tracking Monetary LTV

If you'd like to track LTV as monetary-based revenue, you should increment the value upon the completion of a purchase by the purchase amount. Make sure to configure your app in Localytics to show LTV as "Tracked as Money (US cents)".

LTV must be an integer amount, and the Localytics system requires you pass the number of USD cents as the LTV value in order to track money. For example, if the purchase amount is "USD $2.99", you should pass the integer "299" as the LTV. If the cents don't matter to you, feel free to round up to whole dollar values, but continue to pass the value as cents. If you want to track the rounded value of "USD $3.00", you should pass "300" as the value.

Currently, Localyics only allows LTV tracking in USD. If you want to track other currencies, you could convert the monetary amount to USD on the device before sending to Localytics.

Tracking Non-Monetary LTV

Another way to measure LTV is to track a non-monetary value important to your app. Examples include the number seconds spent engaged with content, or the amount of virtual currency earned. To track these values, send the corresponding integer value to Localytics. Make sure to configure your app in Localytics to show LTV as "Raw Value". Otherwise, Localytics will automatically divide your values by 100 and display a "$" in front of the values in the Dashboard.

LTV Examples

Increment user lifetime value (LTV) on any event using the optional LTV incrementer parameter as seen below.

You can increment LTV with our standard purchased and completed checkout events as follows. The item price and total price values will be used respectively.

Objective-C Swift

[Localytics tagPurchased:@"Shirt"
                  itemId:@"sku-123"
                itemType:@"Apparel"
               itemPrice:@15
              attributes:extraAttributes];
[Localytics tagCompletedCheckout:@50
                       itemCount:@2
                      attributes:extraAttributes];
Localytics.tagPurchased("Shirt", itemId: "sku-123", itemType: "Apparel", itemPrice: 15, attributes: extraAttributes)
Localytics.tagCompletedCheckout(50, itemCount: 2, attributes: extraAttributes)

You can also increment LTV using a custom event by including a customerValueIncrease value.

Objective-C Swift

[Localytics tagEvent:@"Item Purchased"
          attributes:@{@"Item Name" : @"Stickers", @"Aisle" : @"Knick-Knacks"}
   customerValueIncrease:@499];
Localytics.tagEvent("Item Purchased", attributes: ["Item Name": "Stickers", "Aisle": "Knick-Knacks"], customerValueIncrease: 499)

Setting custom dimensions

Custom dimensions are special fields that are used for splitting and filtering data within the Localytics Dashboard and are useful for storing user-level information. Custom dimensions are like sticky event attributes in the sense that once their value is set, it remains set until the value is changed again. Unlike event attributes, custom dimension values are attached to all three types of datapoints (session start, session close, and event) the same way that standard dimensions are which makes their values available within almost every report in the Localytics Dashboard.

Custom dimensions start at an index of 0 and the number of custom dimensions available to you depends on the level of your subscription. Name all of your custom dimensions in the Localytics Dashboard > Settings > Apps > (find app) > Gear icon > Custom Dimensions.

Whenever a datapoint is created, all custom dimension values are attached to the datapoint. Therefore, it is ideal to set custom dimensions as soon as their value is known in all code paths in your app. It is not uncommon to use an analytics callback to set custom dimension values before the start of a session (and the creation of a "session start" datapoint).

Setting a value

Objective-C Swift

[Localytics setValue:@"Trial" forCustomDimension:0];
Localytics.setValue("Trial", forCustomDimension: 0)

Initializing dimensions before session start

Set the value of all custom dimensions as early as possible in your app's code path even if you only set the value to "Not applicable" or "Not available". Having at least some value for each custom dimension instead of nothing will prevent the display of "[Unspecified]" values in the Dashboard and help to make it much more obvious to distinguish intentionally missing values from unintentionally missing values.

  1. In your app delegate header file, ensure that your app delegate conforms to the LLAnalyticsDelegate protocol as follows.

    Objective-C Swift

    @interface YourAppDelegate : UIResponder <UIApplicationDelegate, TVApplicationControllerDelegate, LLAnalyticsDelegate>
    
    class AppDelegate: UIResponder, UIApplicationDelegate, TVApplicationControllerDelegate, LLAnalyticsDelegate {
    
  2. Modify your app delegate as follows to register the Localytics analytics delegate and set any custom dimension values before the first session opens. You will need to modify the custom dimension code below to match your exact custom dimension values.

    Objective-C Swift

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        // ...Localytics initialization code here...
    
        [Localytics setAnalyticsDelegate:self];
    
        // ... rest of didFinishLaunchingWithOptions ...
    
        return YES;
    }
    
    - (void)localyticsSessionWillOpen:(BOOL)isFirst isUpgrade:(BOOL)isUpgrade isResume:(BOOL)isResume
    {
        if (isFirst)
        {
            [Localytics setValue:@"Logged Out" forCustomDimension:0];
            [Localytics setValue:@"0" forCustomDimension:1];
            // ...rest of custom dimensions go here...
        }
    }
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
      // ...Localytics initialization code here...
    
      Localytics.setAnalyticsDelegate(self)
    
      // ... rest of didFinishLaunchingWithOptions ...
    
      return true
    }
    
    func localyticsSessionWillOpen(_ isFirst: Bool, isUpgrade: Bool, isResume: Bool) {
      if isFirst {
        Localytics.setValue("Logged Out", forCustomDimension: 0)
        Localytics.setValue("0", forCustomDimension: 1)
        // ...rest of custom dimensions go here...
      }
    }
    

Clearing a value

Though it may be more appropriate to set a custom dimension value back to an initial state, sometimes you may need to completely clear the value. Setting an an empty string will NOT clear the value. To clear a value use the following code:

Objective-C Swift

[Localytics setValue:nil forCustomDimension:0];
Localytics.setValue(nil, forCustomDimension:0)

Advanced

Installing without CocoaPods

If you are unable to install the SDK using CocoaPods, the following alternative approach will install the SDK and its dependencies.

  1. Delete any existing Localytics files from your project.
  2. Download the latest version of the SDK.
  3. Unzip it and drag Localytics.framework into the top level of your Xcode project in the Project Navigator (Command + 1).
    1. When prompted, use the checkboxes to add the framework to the specific target for which you are compiling. Check the "copy items if needed" box.
    2. By default, XCode will add the framework to the Link Binaries with Libraries section of the Project File. This is incorrect for a dynamically linked framework and will result in errors when running the app. Remove the reference to Localytics.Framework in Link Binaries with Libraries and add it to Embedded Binaries section. Note: This will add a new reference to the Link Binaries with Libraries section that does not need to be removed.
    3. For each target that includes Localytics.Framework repeat the above step.
  4. Add AdSupport.framework, libz.tbd, and SystemConfiguration.framework to your project.
    1. Enter Project Navigator view and click on your project icon. It should be at the top of the Project Navigator.
    2. Select your target from the sidebar or from the dropdown menu, then select the Build Phases tab.
    3. Open the Link Binaries with Libraries expander and click +. Find each library from the list, clicking Add each time.
  5. Add the -ObjC other linker flag to your build settings.
    1. Enter Project Navigator view and click on your project icon. It should be at the top of the Project Navigator.
    2. Select the Build Phases tab.
    3. Select the All option and type Other Linker Flags into the search box.
    4. Double click on the right side of the Other Linker Flags and add the text -ObjC.
  6. When submitting a tvOS app build to iTunes Connect for distribution you'll have to remove the simulator-compatible (x86) version of all frameworks your app uses, including Localytics.

    Rather than shipping a simulator-incompatible library or forcing our users to swap to a "skinny" version of our library at build time, the easiest way to ship without the simulator architecture is to add a script to your build process that removes the "fat" architectures used by the simulator.

    Configure framework slices in Project Settings
    1. Enter Project Naviator view and click on your project icon. It should be at the top of the Project Navigator.
    2. Select your target from the sidebar or from the dropdown menu, then select the Build Phases tab.
    3. Press the + in the top left and add a new run script phase after the embed frameworks step.
    4. Inside the Run Script phase make sure that the Shell is /bin/sh and insert the following code:
      APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
      # This script loops through the frameworks embedded in the application and
      # removes unused architectures.
      find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
      
      do
        FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
        FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
      
        echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"
        EXTRACTED_ARCHS=()
      
        echo "ARCHS = $ARCHS"
      
        INFO_OUTPUT_STR=`lipo -info "$FRAMEWORK_EXECUTABLE_PATH"`
        if [[ $INFO_OUTPUT_STR == *"Non-fat file"* ]]
        then
        	echo "Framework is not a Fat binary, skipping..."
        	continue
        fi
      
        for ARCH in $ARCHS
        do
          echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
          lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
          EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
        done
      
        echo "Merging extracted architectures: ${ARCHS}"
        lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
        rm "${EXTRACTED_ARCHS[@]}"
      
        echo "Replacing original executable with thinned version"
        rm "$FRAMEWORK_EXECUTABLE_PATH"
        mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"
      done
                  
      

You are now ready to continue with the setup process here.

Alternative session management

The standard Localytics session management approach relies on the Localytics SDK to automatically listen for indications of state change (e.g. foreground / background transitions) in your app and then to track the state change accordingly. Most apps are able to use the standard approach. If you are unable to use the standard session management approach, the instructions below will help you to initialize the SDK to achieve the same result as the standard approach.

Use the following initialization instructions instead of those in Getting started. If you have an app with extensive, engaged user activity in the background, as is common with streaming media apps, you may find it necessary reposition calls to openSession and closeSession to achieve the session behavior you desire. Enabling logging when modifying session behavior is often very helpful.

In your application's delegate file:

  1. Import the Localytics SDK under any existing imports.

    Objective-C Swift

    @import Localytics;
    
    import Localytics
    
  2. Add the following code to the start of application:didFinishLaunchingWithOptions:.

    Objective-C Swift

    [Localytics integrate:@"YOUR-LOCALYTICS-APP-KEY"];
    
    if (application.applicationState != UIApplicationStateBackground)
    {
        [Localytics openSession];
    }
    
    Localytics.integrate("YOUR-LOCALYTICS-APP-KEY")
    
    if application.applicationState != .background {
      Localytics.openSession()
    }
    
  3. Add the following code to the start of both applicationDidBecomeActive: and applicationWillEnterForeground:.

    Objective-C Swift

    [Localytics openSession];
    
    Localytics.openSession()
    
  4. Add the following code to the start of applicationDidEnterBackground:.

    Objective-C Swift

    [Localytics closeSession];
    
    Localytics.closeSession()
    
  5. Compile and run your app.

Swift

The Localytics SDK is written in Objective-C but to simplify the process of integrating it with Swift the public APIs have been annotated with nullable and nonnull annotations, collections take advantage of light weight generics, and the SDK is available as a dynamic framework. Calling SDK methods is a straight forward translation from bracket notation to dot notation.

Access to the original AppDelegate

If you are adding methods to the AppDelegate, for access from other parts of the application, it is necessary to take additional steps in Swift. Add the following code to the AppDelegate:

class AppDelegate: UIResponder, UIApplicationDelegate, TVApplicationControllerDelegate {
    static var originalAppDelegate:AppDelegate!
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    AppDelegate.originalAppDelegate = self
        

This will make a globally accessible variable that points to the original AppDelegate. It can be used as follows from anywhere in the application:

AppDelegate.originalAppDelegate.someMethod()

Callbacks

Analytics callbacks

These analytics callbacks are useful for setting the value of a custom dimension or profile attribute before a session opens, firing an event at the beginning or end of a session, or taking action in your app based on an auto-tagged campaign performance event in the Localytics SDK. All Localytics analytics callbacks are called on an internal background thread.

  1. In your app delegate header file, ensure that your app delegate conforms to the LLAnalyticsDelegate protocol as follows.

    Objective-C Swift

    @interface YourAppDelegate : UIResponder <UIApplicationDelegate, LLAnalyticsDelegate>
    
    class AppDelegate: UIResponder, UIApplicationDelegate, LLAnalyticsDelegate {
    
  2. Modify your app delegate as follows to register the Localytics analytics delegate and implement any of the analytics callbacks you require.

    Objective-C Swift

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        // ...Localytics initialization code here...
    
        [Localytics setAnalyticsDelegate:self];
    
        // ... rest of didFinishLaunchingWithOptions ...
    
        return YES;
    }
    
    - (void)localyticsSessionWillOpen:(BOOL)isFirst
                            isUpgrade:(BOOL)isUpgrade
                             isResume:(BOOL)isResume
    {
        // ... do something ...
    }
    
    - (void)localyticsSessionDidOpen:(BOOL)isFirst
                           isUpgrade:(BOOL)isUpgrade
                            isResume:(BOOL)isResume
    {
        // ... do something ...
    }
    
    - (void)localyticsDidTagEvent:(NSString *)
                       attributes:(NSDictionary *)attributes
            customerValueIncrease:(NSNumber *)customerValueIncrease
    {
        // ... do something ...
    }
    
    - (void)localyticsSessionWillClose
    {
        // ... do something ...
    }
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
      // ...Localytics initialization code here...
    
      Localytics.setAnalyticsDelegate(self)
    
      // ... rest of didFinishLaunchingWithOptions ...
    
      return true
    }
    
    func localyticsSessionWillOpen(_ isFirst: Bool, isUpgrade: Bool, isResume: Bool) {
      // ... do something ...
    }
    
    func localyticsSessionDidOpen(_ isFirst: Bool, isUpgrade: Bool, isResume: Bool) {
      // ... do something ...
    }
    
    func localyticsDidTagEvent(_ eventName: String, attributes: [String : Any]?, customerValueIncrease: NSNumber?) {
      // ... do something ...
    }
    
    func localyticsSessionWillClose() {
      // ... do something ...
    }
    

Setting a custom identifier

Once a custom identifier is set, it is attached to each subsequent datapoint, similar to the behavior of custom dimensions. Unlike custom dimensions, however, custom identifiers only end up in export data. They are useful for attaching multiple unique identifiers to a given datapoint for use in joining your Localytics export data with other sources in an enterprise data warehouse. Custom identifiers are not used by the Localytics backend or Dashboard for anything and are just passed through to the export data.

Objective-C Swift

[Localytics setValue:@"Black" forIdentifier:@"Hair Color"];
Localytics.setValue("Black", forIdentifier:"Hair Color")

Creating an explicit App ID

  1. Log in to the Apple Developer console and go to Certificates, Identifiers & Profiles.
  2. Under Identifiers, select App IDs and then click the Add button (+) in the upper-right corner.
  3. Enter a description, select your Team ID as the App ID Prefix, enter an Explicit App ID that exactly matches your Bundle ID, and then click Continue.
  4. Verify the information you entered and then click Register.

Troubleshooting

To gain more insight into whether your Localytics tagging is occuring when expected, you can enable logging in your app using the code below. When looking at logs, a 202 response code indicates that an upload was successful. Be sure to disable logging in production builds. Localytics log output is required when contacting support.

Objective-C Swift

[Localytics setLoggingEnabled:YES];
Localytics.setLoggingEnabled(true)