The Tenjin iOS SDK allows users to track events and installs in their iOS apps. To learn more about Tenjin and our product offering, please visit https://www.tenjin.com.
- 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]
- Xcode 13 requirement, if you’re using iOS SDK v1.12.17 and higher.
- For AppTrackingTransparency, be sure to update your project
.plist
file and addPrivacy - Tracking Usage Description
(NSUserTrackingUsageDescription) along with the text message you want to display to users. This library is only available in iOS 14.0+. - For Apple Search Ads Attribution support, please be sure to upgrade to v1.12.6+ and add the
AdServices.framework
library. This library is only available in iOS 14.3+.
- SDK Integration
- Purchase Events
- Custom Events
- Deferred Deeplink
- Server-to-server integration
- App Subversion
- Impression Level Ad Revenue Integration
- Attribution Info
- Customer User ID
- Analytics Installation ID
- Google DMA parameters
- Retry/cache events and IAP
If you use pods, add pod 'TenjinSDK'
to your Podfile
then run pod install
and skip to step 4 under Steps for Objective-C projects.
If you use SPM, add Tenjin’s SDK package through Xcode with this repository here and skip to step 4 under Steps for Swift projects.
-
Download the latest SDK release here.
-
Drag
TenjinSDK.xcframework
andTenjinSDK.h
to your project under build phases -> "Link Binary With Libraries".
-
Go to your AppDelegate file, by default
AppDelegate.m
, and#import "TenjinSDK.h"
. -
Get your
SDK_KEY
from your app page. Note:SDK_KEY
is unique for each of your app. You can create up to 3 keys for the same app. -
In your
didFinishLaunchingWithOptions
method add:[TenjinSDK initialize:@"<SDK_KEY>"]; [TenjinSDK connect];
-
To enable Tenjin iOS SDK debug logs add:
[TenjinSDK debugLogs];
Here's an example of what your integration in Objective-C projects should look like in your
AppDelegate.m
file:#import "TenjinSDK.h" @implementation TJNAppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [TenjinSDK initialize:@"<SDK_KEY>"]; [TenjinSDK connect]; //All your other stuff ... }
-
Add Objective-C Bridging Header file for swift projects,
- Create a header file
- File -> New -> File -> “Sources”
- Choose “Header” File - > Click Next
- The header file name should “YourProjectName-Bridging-Header” -> Under “Targets” -> Select the app target -> Click "Next"
- In the header file - “YourProjectName-Bridging-Header.h”
- Add - `#import "TenjinSDK.h"`
- Go to the app target and under “Build Settings”
- Go to the section “Swift Compiler - General”
- Go to the sub-section “Objective-C Bridging Header” and drag the header file - “YourProjectName-Bridging-Header.h” to the field.
- Create a header file
-
Get your
SDK_KEY
from your app page. -
In your
didFinishLaunchingWithOptions
method add:TenjinSDK.getInstance("<SDK_KEY>") TenjinSDK.connect()
If you are using Swift 5, use the
getInstance()
method instead ofinit()
. See our sample Swift app. -
To enable Tenjin iOS SDK debug logs add:
TenjinSDK.debugLogs();
Here's an example of what your integration in Swift projects should look like in your
AppDelegate.swift
file:func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. TenjinSDK.getInstance("<SDK_KEY>") TenjinSDK.connect() return true }
Note
Please ensure 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 under suspension.
In the step 7, you can also try alternate initialization to handle deep links from other services. 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 initialize:@"<SDK_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 the test events from your app. You should see live events come in:
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, only in below iOS 14. ATTrackingManager permissions prompt is obligatory from the end of spring 2021.
#import "TenjinSDK.h"
@implementation TJNAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[TenjinSDK initialize:@"<SDK_KEY>"];
if (@available(iOS 14, *)) {
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
[TenjinSDK connect];
}];
} else {
[TenjinSDK connect];
}
}
To comply with Apple’s ATT guidelines, you must provide a description for the ATT permission prompt, then implement the permission request in your application.
Note
You must implement the permission request before serving ads in your game.
Apple requires a description for the ATT permission prompt. You need to set the description with the NSUserTrackingUsageDescription
key in the Info.plist
file of your Xcode project. You have to provide a message that informs the user why you are requesting permission to use device tracking data:
- In your Xcode project navigator, open the
Info.plist
file. - Click the add button (+) beside any key in the property list editor to create a new property key.
- Enter the key name
NSUserTrackingUsageDescription
. - Select a string value type.
- Enter the app tracking transparency message in the value field. Some examples include:
- "We will use your data to provide a better and personalized ad experience."
- "We try to show ads for apps and products that will be most interesting to you based on the apps you use, the device you are on, and the country you are in."
- "We try to show ads for apps and products that will be most interesting to you based on the apps you use."
Note
Apple provides specific app store guidelines that define acceptable use and messaging for all end-user facing privacy-related features. Tenjin does not provide legal advice. Therefore, the information on this page is not a substitute for seeking your own legal counsel to determine the legal requirements of your business and processes, and how to address them.
As part of SKAdNetwork, we created a wrapper method for updatePostbackConversionValue(_:)
.
Our method will register the equivalent SKAdNetwork methods and also send the conversion values to our servers.
updatePostbackConversionValue(\_:)
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.
As of iOS 16.1, which supports SKAdNetwork 4.0, you can now send coarseValue
(String, with possible variants being "low", "medium" or "high") and lockWindow
(Boolean) as parameters on the update postback method:
updatePostbackConversionValue(_ conversionValue: Integer, coarseValue: String)
updatePostbackConversionValue(_ conversionValue: Integer, coarseValue: String, lockWindow: Bool)
-
For iOS version 16.1+ which supports SKAdNetwork 4.0, you can call this method as many times as you want and can make the conversion value lower or higher than the previous value.
-
For iOS versions lower than 16.1 supporting SKAdnetWork versions lower than 4.0, you can call this method and our SDK will automatically detect the iOS version and update
conversionValue
only.
#import "TenjinSDK.h"
@implementation TJNAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[TenjinSDK initialize:@"<SDK_KEY>"];
[TenjinSDK connect];
//
// This will call [SKAdNetwork updatePostbackConversionValue: <Integer between 0 and 63>]
// and also send conversion value to our servers.
//
// You will need to use a value between 0-63.
//
[TenjinSDK updatePostbackConversionValue: <Integer between 0 and 63>];
// For iOS 16.1+ (SKAN 4.0)
[TenjinSDK updatePostbackConversionValue: <Integer between 0 and 63> coarseValue:@"medium"];
[TenjinSDK updatePostbackConversionValue: <Integer between 0 and 63> coarseValue:@"medium" lockWindow:true];
}
}
To specify Tenjin as the destination for your SK Ad Network postbacks, do the following:
- Select
Info.plist
in the Project navigator in Xcode. - Click the Add button (+) beside a key in the property list editor and press Return.
- Type the key name
NSAdvertisingAttributionReportEndpoint
. - Choose String from the pop-up menu in the Type column.
- Enter
https://tenjin-skan.com
These steps are an adaption from Apple's instructions at https://developer.apple.com/documentation/storekit/skadnetwork/configuring_an_advertised_app.
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 initialize:@"<SDK_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.
-
Kindly 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 intend to use Google Ads, you will also need to add: platform
, os_version
, app_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 initialize:@"<SDK_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 specific device-related parameters, use OptOutParams()
. In the example below, we will send ALL device-related parameters except: locale
, timezone
, and build_id
parameters.
[TenjinSDK initialize:@"<SDK_KEY>"];
NSArray *optOutParams = @[@"country", @"timezone", @"language"];
[TenjinSDK optOutParams:optOutParams];
[TenjinSDK connect];
You can automatically opt in or opt out using your CMP consents (purpose 1) which are already saved in the user's device. The method returns a boolean to let you know if it's opted in or out.
optInOutUsingCMP()
[TenjinSDK initialize:@"<SDK_KEY>"];
optInOut = [TenjinSDK optInOutUsingCMP];
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 |
Pass (SKPaymentTransaction *) transaction
and (NSData *)receipt
object, after the verification of the purchase, and then you can pass SKPaymentTransactionStatePurchased
to Tenjin for 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 your user acquisition campaigns using purchase data.
Choose between 15% and 30% App Store’s revenue commission via our new setup. The steps are -
- Go to CONFIGURE --> Apps
- Click on the app you want to change it for
- Under the ‘App Store Commission’ section click ‘Edit’
- Choose 30% or 15% as your desired app store commission.
- Select the start date and end date (Or you can keep the end date blank if you dont want an end date)
- Click Save (note: the 15% commission can be applied only to dates moving forward and not historical dates. So please set the start date from the date you make the change and forward)
IMPORTANT: If you have subscription IAP, you will need to add your app's public key in the Tenjin dashboard. You can retrieve your iOS App-Specific Shared Secret from the iTunes Connect Console > Select your app > Features > In-App Purchases > App-Specific Shared Secret.
Kindly note that you are responsible to send a 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
IMPORTANT: DO NOT SEND CUSTOM EVENTS BEFORE THE CONNECT/INITIALIZATION event (above). The initialization must come before sending any custom events.
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 NSInteger
eventValue
. Tenjin will use this eventValue
as a count or sum for all custom events with the same eventName
.
//send a particular event for when someone swipes and an event value on a part of your app
[TenjinSDK sendEventWithName:@"swipe_right" andValue:1];
Tenjin offers server-to-server integration. If you want to access to the documentation, please send email to [email protected].
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 initialize:@"<SDK_KEY>"];
[TenjinSDK appendAppSubversion:@8888];
[TenjinSDK connect];
Tenjin supports the ability to integrate with the Impression Level Ad Revenue (ILRD) feature from,
- AppLovin
- Unity LevelPlay
- HyperBid
- AdMob
- TopOn
- CAS
- TradPlus
This feature allows you to receive events which correspond to your ad revenue that is affected by each advertisement show to a user. To enable this feature, follow the below instructions.
Warning
ILRD is a paid feature, so please contact your Tenjin account manager to discuss the price at first before sending ILRD events.
Tenjin supports retrieving of attributes, which are required for developers to get analytics installation id (previously known as tenjin reference id). This parameter can be used when there is no advertising id.
Warning
LiveOps Campaigns is a paid feature, so please contact your Tenjin account manager if you are interested in.
You can set and get customer user id to send as a parameter on events.
setCustomerUserId(userId: "user_id")
getCustomerUserId()
[TenjinSDK initialize:@"<SDK_KEY>"];
[TenjinSDK setCustomerUserId:@"user_id"];
userId = [TenjinSDK getCustomerUserId];
You can get the analytics id which is generated randomly and saved in the local storage of the device.
getAnalyticsInstallationId()
[TenjinSDK initialize:@"<SDK_KEY>"];
analyticsId = [TenjinSDK getAnalyticsInstallationId];
If you already have a CMP integrated, Google DMA parameters will be automatically collected by the Tenjin SDK. There’s nothing to implement in the Tenjin SDK if you have a CMP integrated. If you want to override your CMP, or simply want to build your own consent mechanisms, you can use the following:
setGoogleDMAParametersWithAdPersonalization(bool, bool)
[[TeninSDK sharedInstance] setGoogleDMAParametersWithAdPersonalization:adPersonalization adUserData:adUserData];
To explicitly manage the collection of Google DMA parameters, you have the flexibility to opt in or opt out at any time. While the default setting is to opt in, you can easily adjust your preferences using the optInGoogleDMA or optOutGoogleDMA methods, ensuring full control over your data privacy settings:
[TeninSDK optInGoogleDMA];
[TeninSDK optOutGoogleDMA];
You can enable/disable retrying and caching events and IAP when requests fail or users don't have internet connection. These events will be sent after a new event has been added to the queue and user has recovered connection.
setCacheEventSetting(true)
[TenjinSDK setCacheEventSetting:true];