TenjinSDK 1.12.7

TenjinSDK 1.12.7

TestsTested
LangLanguage Obj-CObjective C
License MIT
ReleasedLast Release Oct 2021

Maintained by Christopher Farm, Van Pham, Tenjin Engineering.



TenjinSDK 1.12.7

  • By
  • Tenjin

Please see our Release Notes to see detailed version history.

For Unity-specific instructions, please visit https://github.com/tenjin/tenjin-unity-sdk.

For any issues or support, please contact: [email protected]

Tenjin iOS SDK

The native iOS SDK for Tenjin. Integrate this into your iOS project to get access to the functionality offered at https://www.tenjin.com.

Notes:

  • Xcode 12 is required if using iOS SDK v1.12.0 and higher.
  • For AppTrackingTransparency, be sure update your project .plist file and add Privacy - Tracking Usage Description (NSUserTrackingUsageDescription) along with the text message you want to display to users.
  • For Apple Search Ads Attribution support, please be sure to upgrade to v1.12.6+ and add the AdServices.framework library.

Tenjin initialization:

If you use pods add pod 'TenjinSDK' to your Podfile then run pod install and skip to step 5.
1. Download the latest SDK release here.
2. Drag libTenjinSDK.a and TenjinSDK.h to your project. Note: If you are testing with 32-bit iOS Simulator devices (i386), you will need to use libTenjinSDKUniversal.a instead of libTenjinSDK.a.
3. Add the following Frameworks to your project:
  • AdServices.framework
  • AdSupport.framework
  • AppTrackingTransparency.framework
  • iAd.framework
  • StoreKit.framework

Dashboard

4. Include the linker flags -ObjC under your Build Settings

Dashboard

5. Go to your AppDelegate file, by default AppDelegate.m, and #import "TenjinSDK.h".
6. Get your API_KEY from your Tenjin Organization tab.
7a. In your didFinishLaunchingWithOptions method add:
[TenjinSDK init:@"<API_KEY>"];
[TenjinSDK connect];

Here's an example of what your integration should look like in your AppDelegate.m file:

#import "TenjinSDK.h"

@implementation TJNAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [TenjinSDK init:@"<API_KEY>"];
    [TenjinSDK connect];

    //All your other stuff
    ...
}

If you are using Swift 5, use the getInstance() method instead of init(). See our sample Swift app

NOTE: Please make sure you implement this code on every didFinishLaunchingWithOptions, not only on the first app open of the app. If we notice that you don't follow our recommendation, we can't give you the proper support or your account might be suspended.

7b. Alternate initialization to handle deep links from other services. (DO NOT USE 7a and 7b. You need to use only one.)

If you use other services to produce deferred deep links, you can pass Tenjin those deep links to handle the attribution logic with your Tenjin enabled deep links.

#import "TenjinSDK.h"

@implementation TJNAppDelegate

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

    [TenjinSDK init:@"<API_KEY>"];

    //get your deep link from your other 3rd party service
    NSURL *url = [NSURL withString: @"your_deep_link"];

    //if you have a deep link that's generated from a third party service then pass it to tenjin to handle the attribution of deep links holistically
    if(url) {
      [TenjinSDK connectWithDeferredDeeplink:url];
    }
    else{
      [TenjinSDK connect];
    }

    //All your other stuff
    //...
}

You can verify if the integration is working through our Live Test Device Data Tool. Add your advertising_id or IDFA/GAID to the list of test devices. You can find this under Support -> Test Devices. Go to the SDK Live page and send a test events from your app. You should see live events come in:

Tenjin initialization with ATTrackingManager:

Starting with iOS 14, you have the option to show the initial ATTrackingManager permissions prompt and selection to opt in/opt out users. If the device doesn't accept tracking permission, IDFA will become zero. If the device accepts tracking permission, the connect() method will send the IDFA to our servers. You can also still call Tenjin connect(), without using ATTrackingManager. ATTrackingManager permissions prompt is not obligatory until the early spring of 2021.

#import "TenjinSDK.h"

@implementation TJNAppDelegate

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

    [TenjinSDK init:@"<API_KEY>"];

    if (@available(iOS 14, *)) {
        [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
            [TenjinSDK connect];
        }];
    } else {
        [TenjinSDK connect];
    }
}

SKAdNetwork and Conversion value:

As part of SKAdNetwork, we created wrapper methods for registerAppForAdNetworkAttribution() and updateConversionValue(_:). Our methods will register the equivalent SKAdNetwork methods and also send the conversion values on our servers.

updateConversionValue(_:) 6 bit value should correspond to the in-app event and shouldn’t be entered as binary representation but 0-63 integer. Please refer to this page for how to implement conversion values.

#import "TenjinSDK.h"

@implementation TJNAppDelegate

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

    [TenjinSDK init:@"<API_KEY>"];

    //
    // This will call [SKAdNetwork registerAppForAdNetworkAttribution]
    //
    [TenjinSDK registerAppForAdNetworkAttribution];

    [TenjinSDK connect];

    //
    // This will call [SKAdNetwork updateConversionValue: <YOUR 6 bit value>]
    // and also send conversion value to our servers.
    //
    // You will need to use a value between 0-63 for <YOUR 6 bit value>.
    //
    [TenjinSDK updateConversionValue: <YOUR 6 bit value>];
}

SKAdNetwork and iOS 15+ Advertiser Postbacks

To specify Tenjin as the destination for your SK Ad Network postbacks, do the following:

  1. Select Info.plist in the Project navigator in Xcode.
  2. Click the Add button (+) beside a key in the property list editor and press Return.
  3. Type the key name NSAdvertisingAttributionReportEndpoint.
  4. Choose String from the pop-up menu in the Type column.
  5. Enter https://tenjin-skan.com

These steps are adapted from Apple's instructions at https://developer.apple.com/documentation/storekit/skadnetwork/configuring_an_advertised_app.

Tenjin and GDPR:

As part of GDPR compliance, with Tenjin's SDK you can opt-in, opt-out devices/users, or select which specific device-related params to opt-in or opt-out. OptOut() will not send any API requests to Tenjin and we will not process any events.

To opt-in/opt-out:

#import "TenjinSDK.h"

@implementation TJNAppDelegate

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

  [TenjinSDK init:@"<API_KEY>"];

  if ([self checkOptInValue]) {
      [TenjinSDK optIn];
  }
  else {
      [TenjinSDK optOut];
  }

  [TenjinSDK connect];

  //All your other stuff
  //..
}

-(BOOL) checkOptInValue
{
  // check opt-in value
  // return YES; // if user opted-in
  return NO;
}

To opt-in/opt-out specific device-related parameters, you can use the OptInParams() or OptOutParams(). OptInParams() will only send device-related parameters that are specified. OptOutParams() will send all device-related parameters except ones that are specified.

  • Please note that we require the following parameter to properly track devices in Tenjin's system. If the mandatory parameter is missing the event will not be processed or recorded.

    • developer_device_id

If you plan on using Google Ads, you will also need to add: platform, os_version, locale, device_model, and build_id.

If you want to only get specific device-related parameters, use OptInParams(). In example below, we will only these device-related parameters: ip_address, advertising_id, developer_device_id, limit_ad_tracking, and iad:

[TenjinSDK init:@"<API_KEY>"];

NSArray *optInParams = @[@"ip_address", @"advertising_id", @"developer_device_id", @"limit_ad_tracking", @"iad"];
[TenjinSDK optInParams:optInParams];

[TenjinSDK connect];

If you want to send ALL parameters except specfic device-related parameters, use OptOutParams(). In example below, we will send ALL device-related parameters except: locale, timezone, and build_id parameters.

[TenjinSDK init:@"<API_KEY>"];

NSArray *optOutParams = @[@"country", @"timezone", @"language"];
[TenjinSDK optOutParams:optOutParams];

[TenjinSDK connect];

Device-Related Parameters

Param Description Reference
ip_address IP Address
advertising_id Device Advertising ID iOS
developer_device_id ID for Vendor iOS
limit_ad_tracking limit ad tracking enabled iOS
platform platform iOS
iad Apple Search Ad parameters iOS
os_version operating system version iOS
device device name iOS (hw.machine)
device_model device model iOS (hw.model)
device_model_name device machine iOS (hw.model)
device_cpu device cpu name iOS (hw.cputype)
os_version_release operating system version iOS
build_id build ID iOS (kern.osversion)
locale device locale iOS
country locale country iOS
timezone timezone iOS

Tenjin purchase event integration instructions:

Pass (SKPaymentTransaction *) transaction and (NSData *)receipt object:

After a purchase has been verified and SKPaymentTransactionStatePurchased you can pass Tenjin the transaction which was purchased:

//Get the NSData receipt
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];

//Pass the transaction and the receiptData to Tenjin
[TenjinSDK transaction: transaction andReceipt: receiptData];

Disclaimer: If you are implementing purchase events on Tenjin for the first time, make sure to verify the data with other tools you’re using before you start scaling up you user acquisition campaigns using purchase data.

Subscription IAP

IMPORTANT: If you have subscription IAP, you will need to add your app's public key in the Tenjin dashboard. You can retreive your iOS App-Specific Shared Secret from the iTunes Connect Console > Select your app > Features > In-App Purchases > App-Specific Shared Secret.

Please note that you are responsible to send subscription transaction one time during each subscription interval (i.e. For example, for a monthly subscription, you will need to send us 1 transaction per month).

In the example timeline below, a transaction event should only be sent at the "First Charge" and "Renewal" events. During the trial period, do not send Tenjin the transaction event. Tenjin does not de-dupe duplicate transactions.

For more information on subscriptions, please see: Apple documentation on Working with Subscriptions

Tenjin custom event integration instructions:

IMPORTANT: DO NOT SEND CUSTOM EVENTS BEFORE THE CONNECT/INITIALIZATION event (above). The initialization must come before any custom events are sent.

IMPORTANT: Limit custom event names to less than 80 characters. Do not exceed 500 unique custom event names.

You can also use the Tenjin SDK to pass a custom event:

  • sendEventWithName: (NSString *)eventName and

You can use these to pass Tenjin custom interactions with your app to tie this to user level cost from each acquisition source that you use through Tenjin's platform. Here are some examples of usage:

//send a particular event for when someone swipes on a part of your app
[TenjinSDK sendEventWithName:@"swipe_right"];

Custom events can also pass an NSString eventValue. Tenjin will use this eventValue as a count or sum for all custom events with the same eventName. The eventValue MUST BE AN INTEGER. If the eventValue is not an integer, we will not send the event.

Tenjin deferred deeplink integration instructions:

Tenjin supports the ability to direct users to a specific part of your app after a new attributed install via Tenjin's campaign tracking URLs. You can utilize the registerDeepLinkHandler handler to access the deferred deeplink through params[@"deferred_deeplink_url"] that is passed on the Tenjin campaign tracking URLs. To test you can follow the instructions found here.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //initialize the Tenjin SDK like you normally would for attribution
    [TenjinSDK init:@"<API_KEY>"];
    [TenjinSDK connect]

    //If you want to utilize the deeplink capabilities in Tenjin, utilize the registerDeepLinkHandler to retrieve the deferred_deeplink_url from the params NSDictionary object
    [[TenjinSDK sharedInstance] registerDeepLinkHandler:^(NSDictionary *params, NSError *error) {
        if([params[@"clicked_tenjin_link"] boolValue]){
            if([params[@"is_first_session"] boolValue]){

                //use the params to retrieve deferred_deeplink_url through params[@"deferred_deeplink_url"]
                //use the deferred_deeplink_url to direct the user to a specific part of your app

            } else{

            }
        }
    }];
}

Below are the parameters, if available, that returned in the deferred deeplink callback:

Parameter Description
advertising_id IDFA of the device
developer_device_id IDFV of the device
ad_network Ad Network of the campaign
campaign_id Tenjin campaign ID
campaign_name Tenjin campaign name
site_id Site ID of source app
deferred_deeplink_url The deferred deep-link of the campaign
clicked_tenjin_link Boolean representing if the device was tracked by Tenjin
is_first_session Boolean representing if this is the first session for the device

You can also use the v1.7.2+ SDK for handling post-install logic using the params provided in this registerDeepLinkHandler. For example, if you have a paid app, you can register your paid app install in the following way:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //initialize the Tenjin SDK like you normally would for attribution
    [TenjinSDK init:@"<API_KEY>"];
    [TenjinSDK connect]

    //If you want to utilize the deeplink capabilities in Tenjin, utilize the registerDeepLinkHandler to retrieve the deferred_deeplink_url from the params NSDictionary object
    [[TenjinSDK sharedInstance] registerDeepLinkHandler:^(NSDictionary *params, NSError *error) {

          if([params[@"is_first_session"] boolValue]){
              //send paid app price and revenue to Tenjin

          } else{

          }

    }];
}

Server-to-server integration

Tenjin offers server-to-server integration. If you want to access to the documentation, please send email to [email protected].

App Subversion parameter for A/B Testing (requires DataVault)

If you are running A/B tests and want to report the differences, we can append a numeric value to your app version using the appendAppSubversion method. For example, if your app version 1.0.1, and set appendAppSubversion: @8888, it will report as 1.0.1.8888.

This data will appear within DataVault where you will be able to run reports using the app subversion values.

[TenjinSDK init:@"<API_KEY>"];
[TenjinSDK appendAppSubversion:@8888];
[TenjinSDK connect];