Create a Podfile
file with the below commands.
cd path/to/project
touch Podfile
Edit Podfile
as below.
target '[Project Name]' do
pod 'AirBridge', '1.36.5'
end
Airbridge iOS SDK 1.18.0+ requires CocoaPods 1.11.0+
Run the following commands in your terminal.
cd path/to/project
pod install --repo-update
When no
pod
command is found, installcocoapods
with the below command.
sudo gem install cocoapods
The iOS SDK can be installed through Swift Package Manager (SPM). SDK versions 1.23.0
, 1.24.0
and 1.24.4+
currently support SPM.
Move to "File" → "Add Packages" in Xcode.
Add the Airbridge iOS SDK
Search for "https://github.com/ab180/airbridge-ios-sdk-deploy" once the "Add Packages" window pops up. Select the version to be installed and click the "Add Package" button.
Select Target for Package Installation.
Check Package Installation.
Airbridge will be shown under "Package Dependencies" if the SDK was properly installed.
Download AirBridge.xcframework
Click "Xcode → Project file → General → Frameworks, Libraries, and Embedded Content → +"
Click "Add Other.. → Add Files.." at the bottom right hand corner
Add the AirBridge.xcframework
folder that is in the file downloaded at step 1.
Set AirBridge.xcframework
as "Do not Embed".
Click "Xcode → Project file → General → Frameworks, Libraries, and Embedded Content → +".
Add the 6 frameworks in the table below.
Set these frameworks as "Do not Embed"
Go to "Xcode → Project file → Build Phase → Link Binary with Libraries".
Set the below six frameworks' statuses to Optional
.
Framework | Description |
---|---|
AdSupport.framework | Used to collect IDFA. |
iAd.framework | Used to collect Apple search ads attribution. |
CoreTelephony.framework | Used to collect carrier information. |
StoreKit.framework | Used to collect SKAdNetwork information. |
AppTrackingTransparency.framework | Used to collect tracking authorization status. |
AdServices.framework | Used to collect Apple Search Ads attribution information. (iOS 14.3+) |
Initialize SDK by adding following code at the beginning of the application:didFinishLaunchingWithOptions:
method in the AppDelegate
file.
#import <AirBridge/AirBridge.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
...
}
import AirBridge
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)
// ...
}
If you're using an environment where AppDelegate
doesn't exist (e.g. SwiftUI
), you would initialize the SDK through the App
class under @main
.
// YourprojectApp.swift
import SwiftUI
import AirBridge
@main
struct OnlyUIApp: App {
init() {
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName: "YOUR_APP_NAME")
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
YOUR_APP_NAME
can be found at the "Airbridge dashboard → Settings → Tokens → App Name".
YOUR_APP_SDK_TOKEN
can be found at the "Airbridge dashboard → Settings → Tokens → App SDK Token".
In order to use the SDK, you must agree to the "IDFA terms and conditions" when publishing the application to the App Store.
Click "Yes" to "Does this app use the Advertising Identifier (IDFA)?
Check "Attribute this app Install to a previously served advertisement".
Check "Attribute an action taken within this app to a previously served advertisement".
Check "Limit Ad Tracking Setting in iOS".
Check if "install" events are being sent when installing and running the application.
Events from the SDK are shown on the "Airbridge Dashboard → Raw Data → App Real-time Logs".
Go to "Airbridge Dashboard → Raw Data → App Real-time Logs".
Search for your "iOS IDFA" in the search box.
Logs may be delayed for up to 5 minutes.
Logs will be printed to Xcode if you insert the following at the beginning of the code that initializes the SDK in your AppDelegate
file.
[AirBridge setLogLevel:AB_LOG_ALL];
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
AirBridge.setLogLevel(.LOG_ALL)
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)
The following information is needed at "Airbridge Dashboard → Tracking Link → Deep Link".
iOS URI Scheme
iOS App ID
Enter the URI scheme that will be used, including ://
, in the iOS URI Scheme area as shown in the picture above.
e.g. example://
, yoururischeme://
Attention
The URI scheme must be entered differently for the production app, which is the app that has already been released on app stores or is planning to be released, and the test app.
If the same URI scheme is entered for the production app and test app, the deep link may open an unintended app page.
Go to Identifiers
at https://developer.apple.com/account/resources.
Click identifier of the application that you want to track.
Copy the identifier information to "iOS App ID" at the Airbridge dashboard in the following format: "App ID Prefix" + "." + "Bundle ID" (e.g. 9JA89QQLNQ.com.apple.wwdc)
Go to "Xcode → Project file → Info → URL Types".
From the Airbridge dashboard, copy "iOS URI Scheme" to Xcode's "URL Schemes". (Do not include ://
)
Go to "Xcode → Project file → Signing & Capabilities".
Click "+ Capability" and add "Associated Domains".
Add applinks:YOUR_APP_NAME.airbridge.io
to "Associated Domains".
Add applinks:YOUR_APP_NAME.abr.ge
to "Associated Domains".
YOUR_APP_NAME
can be found at the "Airbridge dashboard → Settings → Tokens → App Name".
Please refer to Troubleshooting → Webcredentials if you want to use the autofill feature.
Events are usually sent through the application(_:open:options:)
method in AppDelegate
for apps that support iOS 12 and below.
Open ios/[Project name]/AppDelegate
.
Send deeplink information to the SDK when the application is opened through schemes by calling the handleURLSchemeDeeplink
method at the beginning of the following function.
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id>*)options
{
[AirBridge.deeplink handleURLSchemeDeeplink:url];
return YES;
}
func application(_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool
{
AirBridge.deeplink()?.handleURLSchemeDeeplink(url)
return true
}
Send deeplink information to the SDK when the application is opened through an universal link by calling the handleUserActivity
method at the beginning of the following function.
- (BOOL)application:(UIApplication*)application
continueUserActivity:(NSUserActivity*)userActivity
restorationHandler:(void (^)(NSArray* _Nullable))restorationHandler
{
[AirBridge.deeplink handleUserActivity:userActivity];
return YES;
}
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool
{
AirBridge.deeplink()?.handle(userActivity)
return true
}
Attention
Links are forwarded to
SceneDelegate
, notAppDelegate
, for projects usingSceneDelegate
. Please refer to the next section on how to receive deep links throughSceneDelegate
.
Deep links are forwarded to the following methods for projects that use SceneDelegate
and support iOS 13+.
When the application was loaded from a "Not running" status.
scene(_:willConnectTo:options:)
All other situations (e.g. background)
Universal link: scene(_:continue:)
Scheme link: scene(_:openURLContexts:)
import UIKit
import AirBridge
@available(iOS 13, *)
class SceneDelegate: UIWindowSceneDelegate {
var window: UIWindow?
// Receive links after the app's killed
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let schemeLinkURL = connectionOptions.urlContexts.first?.url {
// Scheme
AirBridge.deeplink()?.handleURLSchemeDeeplink(schemeLinkURL)
} else if let userActivity = connectionOptions.userActivities.first {
// Universal
AirBridge.deeplink()?.handle(userActivity)
}
// ...
}
// Receive universal link
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
AirBridge.deeplink().handle(userActivity)
// ...
}
// Receive scheme link
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
guard let schemeLinkURL = URLContexts.first?.url else {
return
}
AirBridge.deeplink().handleURLSchemeDeeplink(schemeLinkURL)
// ...
}
}
If you are using SwiftUI
without SceneDelegate
, deep links would be forwarded through onOpenURL
. This method would be added to your App
class under @main
.
import SwiftUI
import AirBridge
@main
@available(iOS 14, *)
struct OnlyUIApp: App {
...
var body: some Scene {
WindowGroup {
ContentView()
.onOpenURL { url in
if url.scheme != "http" && url.scheme != "https" {
// Scheme Link
AirBridge.deeplink()?.handleURLSchemeDeeplink(url)
}
else {
// Universal Link
let userActivity = NSUserActivity(activityType: NSUserActivityTypeBrowsingWeb)
userActivity.webpageURL = url
AirBridge.deeplink().handle(userActivity)
}
}
}
}
}
Attention
If
SceneDelegate
is being used in yourSwiftUI
environment,onOpenUrl
cannot be used. Please refer to the For projects using SceneDelegate section.
Open ios/[Project file]/AppDelegate
.
Use the setDeeplinkCallback
method to setup the callback that will be called when the application is opened through a deep link.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
[AirBridge getInstance:@"YOUR_APP_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
[AirBridge.deeplink setDeeplinkCallback:^(NSString* deeplink) {
// Deeplink from airbridge = YOUR_SCHEME://...
NSLog(@"DeeplinkCallback : %@", deeplink);
}];
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey:
Any]?) -> Bool {
AirBridge.getInstance("YOUR_APP_TOKEN", appName: "YOUR_APP_NAME", withLaunchOptions: launchOptions)
AirBridge.deeplink()?.setDeeplinkCallback({ (deeplink) in
// Code to run when opening app with a deep link
// Airbridge Deeplink = YOUR_SCHEME://...
NSLog("DeeplinkCallback : %@", deeplink)
})
return true
}
Please add the following method to the App
class under @main
.
import SwiftUI
import AirBridge
@main
@available(iOS 14, *)
struct OnlyUIApp: App {
init() {
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName: "YOUR_APP_NAME")
AirBridge.deeplink()?.setDeeplinkCallback { deeplink in
print(deeplink)
}
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
All deep links that open apps are sent to DeeplinkCallback
Of those deep links, "Airbridge deep links" will be sent using the "iOS URI Scheme" (YOUR_SCHEME://...
) that was set in the Airbridge dashboard.A deferred deep link will be sent to DeeplinkCallback
if ATT status is approved or a timeout occurs.
A deferred deep link will contain a deferred=true
query parameter.
For Airbridge iOS SDK 1.10.0 ~ 1.10.9
, the "Airbridge deep link" will be sent as https://YOUR_APP_NAME.airbridge.io/...
.For Airbridge iOS SDK ~1.9.10
, the "Airbridge deep link" will be sent as either https://YOUR_APP_NAME.airbridge.io/...
or YOUR_SCHEME://...
.
If you are using a custom domain as an Airbridge tracking link, follow the below steps. (Replace example.com
with custom domain)
Go to "Xcode → Project file → Signing & Capabilities → Associated Domains".
Click "+" button and add applinks:example.com
.
Open info.plist
.
Add the following value.
Check if the application is run and the deep link event is sent when "Airbridge deep links" are clicked on. Make sure that the deep link follows the "iOS URI Scheme" format configured in your Airbridge dashboard. (e.g. example://
)
Click deep link
See if the deep link event appears at "Airbridge dashboard → Raw Data → App Real-time Logs"
Once a user identifier information is sent to the SDK, all events thereafter will contain the corresponding user identifier information.
[AirBridge.state setUserID:@"personID"];
[AirBridge.state setUserEmail:@"persondoe@airbridge.io"];
[AirBridge.state setUserPhone:@"1(123)123-1234"]
// user alias changed with inserted dictionary.
[AirBridge.state setUserAlias:@{@"key": @"value"}];
// key, value is inserted to existed user alias.
[AirBridge.state addUserAliasWithKey:@"key" value:@"value"];
AirBridge.state()?.setUserID("personID")
AirBridge.state()?.setUserEmail("persondoe@airbridge.io")
AirBridge.state()?.setUserPhone("(123)123-1234")
// user alias changed with inserted dictionary.
AirBridge.state()?.setUserAlias(["key": "value"])
// key, value is inserted to existed user alias.
AirBridge.state()?.addUserAlias(withKey: "key", value: "value")
Name | Description | Limitations |
---|---|---|
ID | User ID | - |
User Email | Hashed by default | |
Phone | User phone number | Hashed by default |
Alias | User alias | - Maximum 10 aliases |
Additional user attributes can be used for a more accurate MTA (Multi-Touch Attribution) analysis, additional internal data analysis, and linking third-party solutions.
// user attributes changed with inserted dictionary.
[AirBridge.state setUserAttributes:@{@"key": @"value"}];
// key, value is inserted to existed user attributes.
[AirBridge.state addUserAttributesWithKey:@"key" value:@"value"];
// user attributes changed with inserted dictionary.
AirBridge.state()?.setUserAttributes(["key": "value" as NSObject])
// 기존의 user attributes 에 해당 key, value 가 추가됩니다.
AirBridge.state()?.addUserAttributes(withKey: "key", value: "value" as NSObject)
Name | Description | Limit |
---|---|---|
Attributes | User attributes | - Maximum 100 attributes |
Make sure that your user information settings are being properly sent through the SDK.
Configure user identifier information.
Send an event using the SDK.
Click the event at "Airbridge dashboard → Raw Data → App Real-time Logs"
Check if the user information is correctly sent under the user
block.
Setup a device alias through the Airbridge SDK. The alias will be sustained even after the app closes, unless otherwise deleted.
[AirBridge.state setDeviceAliasWithKey: "ADD_YOUR_KEY", value: "AND_YOUR_VALUE"];
[AirBridge.state removeDeviceAliasWithKey: "DELETE_THIS_KEY"];
[AirBridge.state clearDeviceAlias];
AirBridge.state()?.setDeviceAlias(key: "ADD_YOUR_KEY", value: "AND_YOUR_VALUE")
AirBridge.state()?.removeDeviceAlias(key: "DELETE_THIS_KEY")
AirBridge.state().clearDeviceAlias()
Method | Description |
---|---|
| Add the key value pair to the device identifier. |
| Delete the corresponding device alias. |
| Delete all device aliases. |
When important user actions occur, in-app events can be sent to measure the performance of each channel.
All event parameters are optional. However, more information about the event will help provide a more accurate analysis.
Send events with the SDK.
#import <AirBridge/ABInAppEvent.h>
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:@"category"];
[event setAction:@"action"];
[event setLabel:@"label"];
[event setValue:@(123)];
[event setCustoms:@{@"key": @"value"}];
// Semantic Attributes Option 1
ABSemanticAttributes* semanticAttributes = [[ABSemanticAttributes alloc] init];
semanticAttributes.transactionID = @"transaction_123";
[event setSemanticAttributes:semanticAttributes];
// Semantic Attributes Option 2
// For more details, please check following page
// https://developers.airbridge.io/docs/event-structure#semantic-attributes
[event setSemantics:@{@"transactionID": @"transaction_123"}];
[event send];
let event = ABInAppEvent()
event?.setCategory("category")
event?.setAction("action")
event?.setLabel("label")
event?.setValue(123)
event?.setCustoms(["key": "value"])
// Semantic Attributes Option 1
let semanticAttributes = ABSemanticAttributes()
semanticAttributes?.transactionID = "transaction_123"
event?.setSemanticAttributes(semanticAttributes)
// Semantic Attributes Option 2
// For more details, please check following page
// https://developers.airbridge.io/docs/event-structure#semantic-attributes
event?.setSemantics(["transactionID": "transaction_123"])
event?.send()
Parameter | Description |
---|---|
setCategory | Event name (required) |
setAction | Event attribute 1 |
setLabel | Event attribute 2 |
setValue | Event attribute value |
setCustoms | Additional custom attributes |
setSemanticAttributes | Additional semantic attributes (Map) |
Send standard user events with the SDK.
setAction
, setLabel
, setValue
, setCustoms
, setSemantics
, setSemanticAttributes
can also be used when sending standard events.
#import <AirBridge/ABUser.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
ABUser* user = [[ABUser alloc] init];
user.ID = @"testID";
user.email = @"testID@ab180.co";
user.phone = @"000-0000-0000";
user.alias = @{
@"key": @"value",
};
user.attributes = @{
@"key": @"value",
};
[AirBridge.state setUser:user];
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.signUp];
[event send];
let user = ABUser()
user.id = "testID"
user.email = "testID@ab180.co"
user.phone = "000-0000-0000"
user.attributes = [
"key": "value" as NSObject,
]
user.alias = [
"key": "value",
]
AirBridge.state().setUser(user)
let event = ABInAppEvent()
event?.setCategory(ABCategory.signUp)
event?.send()
#import <AirBridge/ABUser.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
ABUser* user = [[ABUser alloc] init];
user.ID = @"testID";
user.email = @"testID@ab180.co";
user.phone = @"000-0000-0000";
user.alias = @{
@"key": @"value",
};
user.attributes = @{
@"key": @"value",
};
[AirBridge.state setUser:user];
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.signIn];
[event send];
let user = ABUser()
user.id = "testID"
user.email = "testID@ab180.co"
user.phone = "000-0000-0000"
user.attributes = [
"key": "value" as NSObject,
]
user.alias = [
"key": "value",
]
AirBridge.state().setUser(user)
let event = ABInAppEvent()
event?.setCategory(ABCategory.signIn)
event?.send()
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.signOut];
[AirBridge.state setUser:[[ABUser alloc] init]];
let event = ABInAppEvent()
event?.setCategory(ABCategory.signOut)
event?.send()
AirBridge.state().setUser(ABUser())
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.viewHome];
[event send];
let event = ABInAppEvent()
event?.setCategory(ABCategory.viewHome)
event?.send()
#import <AirBridge/ABProduct.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
#import <AirBridge/ABSemanticsKey.h>
ABProduct* product1 = [[ABProduct alloc] init];
product1.idx = @"idx1";
product1.name = @"name1";
product1.price = @100;
product1.currency = @"USD";
product1.orderPosition = @1;
product1.quantity = @1;
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.viewProductDetail];
[event setSemantics:@{
ABSemanticsKey.products: @[product1.toDictionary],
}];
[event send];
let product1 = ABProduct()
product1.idx = "idx1"
product1.name = "name1"
product1.price = 100
product1.currency = "USD"
product1.orderPosition = 1
product1.quantity = 1
let event = ABInAppEvent()
event?.setCategory(ABCategory.viewProductDetail)
event?.setSemantics([
ABSemanticsKey.products: [
product1.toDictionary(),
],
])
event?.send()
#import <AirBridge/ABProduct.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
#import <AirBridge/ABSemanticsKey.h>
ABProduct* product1 = [[ABProduct alloc] init];
product1.idx = @"idx1";
product1.name = @"name1";
product1.price = @100;
product1.currency = @"USD";
product1.orderPosition = @1;
product1.quantity = @1;
ABProduct* product2 = [[ABProduct alloc] init];
product2.idx = @"idx2";
product2.name = @"name2";
product2.price = @200;
product2.currency = @"USD";
product2.orderPosition = @2;
product2.quantity = @2;
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.viewProductList];
[event setSemantics:@{
ABSemanticsKey.products: @[
product1.toDictionary,
product2.toDictionary,
],
ABSemanticsKey.productListID: @"listID",
}];
[event send];
let product1 = ABProduct()
product1.idx = "idx1"
product1.name = "name1"
product1.price = 100
product1.currency = "USD"
product1.orderPosition = 1
product1.quantity = 1
let product2 = ABProduct()
product2.idx = "idx2"
product2.name = "name2"
product2.price = 200
product2.currency = "USD"
product2.orderPosition = 2
product2.quantity = 2
let event = ABInAppEvent()
event?.setCategory(ABCategory.viewProductList)
event?.setSemantics([
ABSemanticsKey.products: [
product1.toDictionary(),
product2.toDictionary(),
],
ABSemanticsKey.productListID: "productListID",
])
event?.send()
#import <AirBridge/ABProduct.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
#import <AirBridge/ABSemanticsKey.h>
ABProduct* product1 = [[ABProduct alloc] init];
product1.idx = @"idx1";
product1.name = @"name1";
product1.price = @100;
product1.currency = @"USD";
product1.orderPosition = @1;
product1.quantity = @1;
ABProduct* product2 = [[ABProduct alloc] init];
product2.idx = @"idx2";
product2.name = @"name2";
product2.price = @200;
product2.currency = @"USD";
product2.orderPosition = @2;
product2.quantity = @2;
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.viewSearchResult];
[event setSemantics:@{
ABSemanticsKey.products: @[
product1.toDictionary,
product2.toDictionary,
],
ABSemanticsKey.query: @"query",
}];
[event send];
let product1 = ABProduct()
product1.idx = "idx1"
product1.name = "name1"
product1.price = 100
product1.currency = "USD"
product1.orderPosition = 1
product1.quantity = 1
let product2 = ABProduct()
product2.idx = "idx2"
product2.name = "name2"
product2.price = 200
product2.currency = "USD"
product2.orderPosition = 2
product2.quantity = 2
let event = ABInAppEvent()
event?.setCategory(ABCategory.viewSearchResult)
event?.setSemantics([
ABSemanticsKey.products: [
product1.toDictionary(),
product2.toDictionary(),
],
ABSemanticsKey.query: "query",
])
event?.send()
#import <AirBridge/ABProduct.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
#import <AirBridge/ABSemanticsKey.h>
ABProduct* product1 = [[ABProduct alloc] init];
product1.idx = @"idx1";
product1.name = @"name1";
product1.price = @100;
product1.currency = @"USD";
product1.orderPosition = @1;
product1.quantity = @1;
ABProduct* product2 = [[ABProduct alloc] init];
product2.idx = @"idx2";
product2.name = @"name2";
product2.price = @200;
product2.currency = @"USD";
product2.orderPosition = @2;
product2.quantity = @2;
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.addToCart];
[event setSemantics:@{
ABSemanticsKey.products: @[
product1.toDictionary,
product2.toDictionary,
],
ABSemanticsKey.cartID: @"cartID",
ABSemanticsKey.currency: @"currency"
}];
[event setValue:@300];
[event send];
let product1 = ABProduct()
product1.idx = "idx1"
product1.name = "name1"
product1.price = 100
product1.currency = "USD"
product1.orderPosition = 1
product1.quantity = 1;
let product2 = ABProduct()
product2.idx = "idx2"
product2.name = "name2"
product2.price = 200
product2.currency = "USD"
product2.orderPosition = 2
product2.quantity = 2;
let event = ABInAppEvent()
event?.setCategory(ABCategory.addToCart)
event?.setSemantics([
ABSemanticsKey.products: [
product1.toDictionary(),
product2.toDictionary(),
],
ABSemanticsKey.cartID: "cartID",
ABSemanticsKey.currency: "KRW",
])
event.setValue(300)
event?.send()
#import <AirBridge/ABProduct.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
#import <AirBridge/ABSemanticsKey.h>
ABProduct* product1 = [[ABProduct alloc] init];
product1.idx = @"coke_zero";
product1.name = @"Coke Zero";
product1.price = @100;
product1.currency = @"USD";
product1.orderPosition = @1;
product1.quantity = @1;
ABProduct* product2 = [[ABProduct alloc] init];
product2.idx = @"burger_cheese_double";
product2.name = @"Double Cheeseburger";
product2.price = @200;
product2.currency = @"USD";
product2.orderPosition = @2;
product2.quantity = @2;
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.purchase];
[event setSemantics:@{
ABSemanticsKey.products: @[
product1.toDictionary,
product2.toDictionary,
],
ABSemanticsKey.transcationID: @"transcationID",
ABSemanticsKey.currency: @"currency",
ABSemanticsKey.inAppPurchased: @YES
}];
[event setValue:@300];
[event send];
let product1 = ABProduct()
product1.idx = "coke_zero"
product1.name = "Coke Zero"
product1.price = 100
product1.currency = "USD"
product1.orderPosition = 1
product1.quantity = 1
let product2 = ABProduct()
product2.idx = "burger_cheese_double"
product2.name = "Double Cheeseburger"
product2.price = 200
product2.currency = "USD"
product2.orderPosition = 2
product2.quantity = 2
let event = ABInAppEvent()
event?.setCategory(ABCategory.purchase)
event?.setSemantics([
ABSemanticsKey.products: [
product1.toDictionary(),
product2.toDictionary(),
],
ABSemanticsKey.transactionID: "transactionID",
ABSemanticsKey.currency: "KRW",
ABSemanticsKey.inAppPurchased: true
])
event?.setValue(300)
event?.send()
Make sure that the events are being properly sent through the SDK.
Send an event with the SDK.
Check if the event shows up at "Airbridge dashboard → Raw Data → App Real-time Logs".
Restricted SDK does not collect device IDs, including Ad ID. The restricted SDK will be available starting from v1.34.9
.
1. Create the Podfile
with the following command.
cd path/to/project
touch Podfile
2. Fill in the Podfile
as follows.
target '[Project Name]' do
pod 'AirBridgeRestricted'
end
Airbridge iOS SDK 1.18.0+ requires CocoaPods 1.11.0+
3. Open the terminal and enter the following command.
cd path/to/project
pod install --repo-update
When no
pod
command is found, installcocoapods
with the below command.
sudo gem install cocoapods
AirBridge.framework(restricted) : Download
Protection against SDK spoofing is possible once you set up an SDK signature. Settings can be applied by calling setSDKSignatureSecret
before the SDK initialization code.
[AirBridge setSDKSignatureSecretWithID: "YOUR_SDK_SIGNATURE_SECRET_ID", secret: "YOUR_SDK_SIGNATURE_SECRET"];
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
AirBridge.setSDKSignatureSecret(id: "YOUR_SDK_SIGNATURE_SECRET_ID", secret: "YOUR_SDK_SIGNATURE_SECRET")
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)
The SDK Signature Credentials are required for the SDK Signature setup. Refer to this article to learn how to create them.
email
and phone
information are hashed by default. (SHA256)
Call setIsUserInfoHashed
at the beginning of the code that initializes the SDK to change this setting.
// Disable user information hashing
[AirBridge setIsUserInfoHashed:NO];
[AirBridge getInstance:@"YOUR_APP_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
// Disable user information hashing
AirBridge.setIsUserInfoHashed(false)
AirBridge.getInstance("YOUR_APP_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)
Call setSessionTimeout
at the beginning of the code that initializes the SDK to change this setting.
Session timeout is in milliseconds and must range between 0 and 604800000 (7 days).
Default value is 1000 * 60 * 5
(5 minutes).
[AirBridge setSessionTimeout:1000 * 60 * 5];
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
AirBridge.setSessionTimeout(1000 * 60 * 5)
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)
Use this function if privacy laws apply, and data should only be collected and transferred with consent. (e.g GDPR, CCPA)
If autoStartTrackingEnabled
is set to NO (false)
before the SDK initialization code, events will not be sent before the startTracking
function is called. This includes events such as "deep link open".
AirBridge.autoStartTrackingEnabled = NO;
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
[AirBridge startTracking];
AirBridge.setAutoStartTrackingEnabled(false)
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)
AirBridge.startTracking()
Attention
This is not an essential setting function. Please check if it's a necessary function before you set it up.
Opt-Out is a policy where user information is used until the user refuses.
After setting setAutoStartTrackingEnabled
to true
, call the stopTracking
function at the point where events cannot be collected. From the point when the stopTracking
function is called, events are not collected.
#import <AirBridge/AirBridge.h>
AirBridge.autoStartTrackingEnabled = YES;
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
[AirBridge stopTracking];
import Airbridge
AirBridge.setAutoStartTrackingEnabled(true)
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName: "YOUR_APP_NAME", withLaunchOptions: launchOptions)
AirBridge.stopTracking()
The SDK will send all deep link events when the app is opened using a deep link.
If setIsTrackAirbridgeDeeplinkOnly
is set as YES (true)
at the beginning of the code that initializes the SDK, the SDK will only send deep link events that use "Airbridge deep links".
// Send deeplink events only when application is opened with `Airbridge deeplinks`
[AirBridge setIsTrackAirbridgeDeeplinkOnly:YES];
[AirBridge getInstance:@"YOUR_APP_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
// Send deeplink events only when application is opened with `Airbridge deeplinks`
AirBridge.setIsTrackAirbridgeDeeplinkOnly(true)
AirBridge.getInstance("YOUR_APP_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)
The Airbridge SDK can track Facebook deferred App Links through the following settings.
Install the Facebook SDK: https://developers.facebook.com/docs/ios/getting-started.
Open ios/[Project name]/AppDelegate
.
Set setIsFacebookDeferredAppLinkEnabled
to YES
(true
) at the beginning of the code that initializes the Airbridge SDK.
[AirBridge setIsFacebookDeferredAppLinkEnabled:YES];
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
AirBridge.setIsFacebookDeferredAppLinkEnabled(true)
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName: "YOUR_APP_NAME", withLaunchOptions: launchOptions)
Please refer to this page for more information on app uninstall tracking.
Use handleNotificationDeeplink
to send the deep link event to the SDK when users click a push notification.
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
if (UIApplication.sharedApplication.applicationState == UIApplicationStateInactive || UIApplication.sharedApplication.applicationState == UIApplicationStateBackground) {
NSURL* url = // deeplink of push notification's payload
[AirBridge.deeplink handleNotificationDeeplink:url];
}
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler API_AVAILABLE(ios(10.0))
{
if ((UIApplication.sharedApplication.applicationState == UIApplicationStateInactive || UIApplication.sharedApplication.applicationState == UIApplicationStateBackground)
&& [response.actionIdentifier isEqual:UNNotificationDefaultActionIdentifier])
{
NSURL* url = // deeplink of push notification's payload
[AirBridge.deeplink handleNotificationDeeplink:url];
}
}
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable : Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)
{
if UIApplication.shared.applicationState == .inactive || UIApplication.shared.applicationState == .background {
let url = // deeplink of push notification's payload
AirBridge.deeplink()?.handleNotificationDeeplink(url)
}
}
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse, withCompletionHandler
completionHandler: @escaping () -> Void)
{
if UIApplication.shared.applicationState == .inactive || UIApplication.shared.applicationState == .background,
response.actionIdentifier == UNNotificationDefaultActionIdentifier
{
let url = // deeplink of push notification's payload
AirBridge.deeplink()?.handleNotificationDeeplink(url)
}
}
When the AppTrackingTransparency.framework is used to present an app-tracking authorization request to the user, IDFA will not be collected when the install event occurs because the install event occurs before the selection.
If trackingAuthorizeTimeout
is called before the SDK initialization code, the install event will be sent after the timeout
period or delayed until an ATT option is selected.
trackingAuthorizeTimeout
is in milliseconds.
Install events can be delayed for as long as the trackingAuthorizeTimeout
period.
By default, trackingAuthorizeTimeout
is reset every time the App restarts. To prevent this, you can set isRestartTrackingAuthorizeTimeout
as NO
or false
.
A deferred deep link will be sent to DeeplinkCallback
if ATT status is aprroved or a timeout occurs.
AirBridge.setting.trackingAuthorizeTimeout = 30 * 1000;
AirBridge.setting.isRestartTrackingAuthorizeTimeout = NO;
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
AirBridge.setting()?.trackingAuthorizeTimeout = 30 * 1000
AirBridge.setting()?.isRestartTrackingAuthorizeTimeout = false
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)
When an event transmission failure occurs, the Airbridge SDK will store the event and retry at a later time. The following settings will allow you to limit the storage used for such events.
// Event count limit
[AirBridge.setting setEventMaximumBufferCount:newValue]
// Event size limit (Byte)
[AirBridge.setting setEventMaximumBufferSize:newValue]
// Event count limit
AirBridge.setting().setEventMaximumBufferCount(newValue)
// Event size limit (Byte)
AirBridge.setting().setEventMaximumBufferSize(newValue)
Get attribution result data using the Airbridge SDK.
AirBridge.setting().attributionCallback = { (attribution: [String : String]) in
// Process attribution data...
}
[AirBridge.setting setAttributionCallback:^(NSDictionary<NSString *,NSString *> * _Nonnull attribution) {
// Process attribution data...
}];
Below is a list of data fields that will be retrieved through the callback.
Field | Description |
---|---|
attributedChannel | Channel (String) |
attributedCampaign | Campaign (String) |
attributedAdGroup | Ad Group (String) |
attributedAdCreative | Ad Creative (String) |
attributedContent | Content (String) |
attributedTerm | Keyword (String) |
attributedSubPublisher | Sub Publisher (String) |
attributedSubSubPublisher1 | Sub-sub Publisher 1 (String) |
attributedSubSubPublisher2 | Sub-sub Publisher 2 (String) |
attributedSubSubPublisher3 | Sub-sub Publisher 3 (String) |
If the event is unattributed, below is an example of the response you'll get.
{
"attributedChannel": "unattributed"
}
Guidelines for using attribution result data
Attribution data exists
Attribution data is forwarded within 40 seconds of SDK initialization.
If the app was closed and attribution data wasn't received, attribution data is forwarded within 40 seconds when the app is opened again.
On very rare occasions, attribution data could take up to 5 minutes to be received.
Attribution data does not exist
Attribution data will be received 3 hours after SDK initialization.
It is not recommended to utilize these attribution values for real-time processing
Airbridge doesn't track life-cycle event that occur within session timeout as default. You can track these events with below option.
[AirBridge.setting setTrackInSessionLifeCycleEventEnabled:YES];
AirBridge.setting().setTrackInSessionLifeCycleEventEnabled(true)
To comply with the Digital Markets Act (DMA), user consent must be shared with Airbridge. For detailed information about the DMA and the guidelines for advertisers, refer to this article.
Note that consent from all end users in the European Economic Area (EEA) should always be shared with Airbridge.
1. Confirm whether the end user launched the app in the EEA. If the end user did launch the app in the EEA (eea=1
) and DMA applies, confirm whether the consent values are already stored for the session. If there are consent values stored, continue to Step 3.
If the end user launched the app from outside the EEA, it is not necessary to collect user consent.
Note
Airbridge cannot provide guidance on storing the user response data and implementing the prompts. For assistance, consult legal professionals.
2. If there are no consent values stored, proceed to obtain user consent, such as with a privacy prompt. You must collect the adPersonalization
and adUserData
values in this step.
Attention
Advertisers must collect user consent data from all existing and new users in the EEA region at least once starting March 6, 2024.
The table below illustrates the consent data that must be sent to Airbridge. The eea
value is neither a direct response from the user nor automatically filled in by Airbridge. Advertisers should determine the eea
value based on whether the user is in the EEA and the DMA applies or not.
Field Name in Airbridge |
Field Name in Google |
Description |
---|---|---|
<string> |
| Indicates whether the user is in the EEA and the DMA applies or not. The value is neither a direct response from the user nor automatically filled in by Airbridge. Determine the appropriate value based on whether the user is located and whether the DMA applies or not. Values other than - - |
<string> |
| Indicates whether the user gave Google consent to use their data for ad personalization. Values other than - - |
<string> |
| Indicates whether the user gave consent to send their data to Google for ad-related purposes. Values other than - - |
3. Initialize the Airbridge SDK and share the consent values with Airbridge before collecting the end user’s personal data.
Attention
Pay attention to the following.
Use the field names specified by Airbridge:
eea
,adPersonalization
, andadUserData
.Fill in
0
or1
in accordance with the consent data collected.
// AppDelegate.swift
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]?
) {
AirBridge.setAutoStartTrackingEnabled(false)
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)
// Based on actual region
AirBridge.state()?.UserAlias(withKey:"eea", value:"0" or "1")
// Based on actual user consent
AirBridge.state()?.UserAlias(withKey:"adPersonalization", value:"0" or "1")
AirBridge.state()?.UserAlias(withKey:"adUserData", value:"0" or "1")
AirBridge.startTracking()
}
// AppDelegate.m
- (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
AirBridge.autoStartTrackingEnabled = NO;
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
// Based on actual region
[AirBridge.state addUserAliasWithKey:@"eea" value:"0" or "1"];
// Based on actual user consent
[AirBridge.state addUserAliasWithKey:@"adPersonalization" value:"0" or "1"];
[AirBridge.state addUserAliasWithKey:@"adUserData" value:"0" or "1"];
[AirBridge startTracking];
}
While basic events (e.g. "install", "open", "deep link open") can be automatically tracked by only installing the iOS SDK in your hybrid app, in-app events (e.g. sign-up, purchase, etc.) cannot be tracked as they are actually in-browser events that occur within a website of the WebView environment. Airbridge provides a simpler way to track in-app events by enabling the iOS SDK to automatically pull all events from the web SDK that is installed on the website of the WebView environment. This replaces the hassle of having to create bridge functions between native and WebView environments.
Attention
Please note that in order to utilize this feature, both SDKs must be installed; Android SDK on the mobile native environment and web SDK on the website of the WebView environment.
The Airbridge iOS SDK can send events instead of the Airbridge Web SDK installed on your WebView website.
Add Airbridge.webInterface
under the WebView configuration controller.
WKWebViewConfiguration* configuration = [[WKWebViewConfiguration alloc] init];
WKUserContentController* controller = [[WKUserContentController alloc] init];
[AirBridge.webInterface injectTo:controller withWebToken:@"YOUR_WEB_TOKEN"];
configuration.userContentController = controller;
WKWebView* webview = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
let configuration = WKWebViewConfiguration()
let controller = WKUserContentController()
AirBridge.webInterface()?.inject(to: controller, withWebToken: "YOUR_WEB_TOKEN")
configuration.userContentController = controller
webView = WKWebView(frame: .zero, configuration: configuration)
YOUR_WEB_TOKEN
can be found at the "Airbridge dashboard → Settings → Tokens → Web SDK Token".
If the app is using Autofill and no webcredentials
are set, the application's autofill passwords are saved to applinks:YOUR_APP_NAME.airbridge.io
or applinks:YOUR_APP_NAME.abr.ge
.
Follow the steps below to change the location of where the passwords will be saved to. Change example.com
to the domain you will be saving autofill passwords to.
1. Host the following JSON at https://example.com/.well-known/apple-app-site-association
.
{
"webcredentials": {
"apps": ["TEAM_ID.APP_BUNDLE_ID"]
}
}
TEAM_ID.APP_BUNDLE_ID
example: 9JA89QQLNQ.com.apple.wwdc
2. Go to "Xcode → Project file → Signing & Capabilities → Associated Domains".
3. Click "+" and add webcredentials:example.com
.
Airbridge iOS SDK v1.28.0+ no longer supports Bitcode. (Bitcode has been deprecated since Xcode 14)
This could lead to compile errors for the project if Bitcode is used.
Textld: XCFrameworkIntermediates/AirBridge/AirBridge.framework/AirBridge(AirBridge-arm64-master.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE)
Please add the following to your Podfile to prevent this.
installer.pods_project.targets.each do |target|
target.build_configurations.each do |configuration|
configuration.build_settings['ENABLE_BITCODE'] = 'NO'
end
end
Or you can set "ENABLE_BITCODE" to "NO" in Xcode.
Please note that .ipa files using Bitcode are automatically deleted by the Appstore due to the Bitcode deprecation.
Airbridge iOS SDK v1.28.0+ does not support Xcode 13, along with iOS 9 and iOS 10.
If the above Xcode/iOS needs to be supported, please use iOS SDK v1.27.0 and below.
Before updating the SDK, please review the following information.
With support for the privacy manifest, the Static Library has been changed to a Dynamic Library. If you are installing directly, change Airbridge.xcframework to Embed Without Signing in Project's [General]>[Frameworks, Libraries, and Embedded Content].
Was this page helpful?