SDK Setup


iOS SDKiOS SDK


SDK Installation

Cocoapods

1. Create a Podfile file with the below commands.
cd path/to/project
touch Podfile
2. Edit Podfile as below.
target '[Project Name]' do
    pod 'AirBridge', '1.24.0'
end

Airbridge iOS SDK 1.18.0+ requires Cocoapods 1.11.0+

3. Run the following commands in your terminal.
cd path/to/project
pod install --repo-update

When no pod command is found, install cocoapods with the below command.
sudo gem install cocoapods


Swift Package Manager (SPM)

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.

1. Move to "File" → "Add Packages" in Xcode.
15821582
2. 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.

22362236
3. Select Target for Package Installation.
22362236
4. Check Package Installation.

Airbridge will be shown under "Package Dependencies" if the SDK was properly installed.

18181818

Direct Installation

1. Adding the AirBridge.framework
  1. Download AirBridge.framework
  2. Click "Xcode → Project file → General → Frameworks, Libraries, and Embedded Content → +"
  3. Click "Add Other.. → Add Files.." at the bottom right hand corner
  4. Add the AirBridge.framework folder that is in the file downloaded at step 1.
2. Adding Dependency Frameworks
  1. Click "Xcode → Project file → General → Frameworks, Libraries, and Embedded Content → +".
  2. Add the 6 frameworks in the table below. (Set as Do not Embed)
  3. Go to "Xcode → Project file → Build Phase → Link Binary with Libraries".
  4. 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+)


Project Setup

Initialization

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_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
    ...
}
import AirBridge

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    AirBridge.getInstance("YOUR_APP_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)
    ...
}

YOUR_APP_NAME can be found at the "Airbridge dashboard → Settings → Tokens → App Name".
YOUR_APP_TOKEN can be found at the "Airbridge dashboard → Settings → Tokens → App SDK Token".

Accept IDFA Terms and Conditions

In order to use the SDK, you must agree to the "IDFA terms and conditions" when publishing the application to the App Store.

  1. Click "Yes" to "Does this app use the Advertising Identifier (IDFA)?
  2. Check "Attribute this app Install to a previously served advertisement".
  3. Check "Attribute an action taken within this app to a previously served advertisement".
  4. Check "Limit Ad Tracking Setting in iOS".
22402240

Testing the SDK

Check if "install" events are being sent when installing and running the application.

Check in the Airbridge Dashboard

Events from the SDK are shown on the "Airbridge Dashboard → Raw Data → App Real-time Logs".

  1. Go to "Airbridge Dashboard → Raw Data → App Real-time Logs".
  2. Search for your "iOS IDFA" in the search box.

Logs may be delayed for up to 5 minutes.

Check with Logs

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_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
AirBridge.setLogLevel(.LOG_ALL)
AirBridge.getInstance("YOUR_APP_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)



Deep Link Setup


Dashboard Setup

The following information is needed at "Airbridge Dashboard → Tracking Link → Deep Link".

  • iOS URI Scheme
  • iOS App ID
24822482

iOS URI Scheme

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://

🚧

Airbridge supports lowercase letters, numbers, and some special characters (-, +, .) for URI Schemes.

iOS App ID

  1. Go to Identifiers at https://developer.apple.com/account/resources.
  2. Click identifier of the application that you want to track.
  3. 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)
20482048



Project Setup

Scheme

  1. Go to "Xcode → Project file → Info → URL Types".
  2. From the Airbridge dashboard, copy "iOS URI Scheme" to Xcode's "URL Schemes". (Do not include ://)
768768

Universal Link

  1. Go to "Xcode → Project file → Signing & Capabilities".
  2. Click "+ Capability" and add "Associated Domains".
  3. Add applinks:YOUR_APP_NAME.airbridge.io to "Associated Domains".
  4. Add applinks:YOUR_APP_NAME.deeplink.page 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.

Send deeplink information to SDK

For projects using AppDelegate

Events are usually sent through the application(_:open:options:) method in AppDelegate for apps that support iOS 12 and below.

  1. Open ios/[Project name]/AppDelegate.

  2. 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
}
  1. When targeting iOS 8.x or earlier, call the handleURLSchemeDeeplink method at the beginning of the following function.
- (BOOL)application:(UIApplication*)application
            openURL:(NSURL*)url
  sourceApplication:(NSString*)sourceApplication 
         annotation:(id)annotation
{
    [AirBridge.deeplink handleURLSchemeDeeplink:url];

    return YES;
}
func application(_ application: UIApplication,
                 open url: URL,
                 sourceApplication: String?,
                 annotation: Any) -> Bool
{
    AirBridge.deeplink()?.handleURLSchemeDeeplink(url)
    
    return true;
}
  1. Send deeplink information to the SDK when the application is opened through an universal link by calling the handleUniversalLink method at the beginning of the following function.
-  (BOOL)application:(UIApplication*)application
continueUserActivity:(NSUserActivity*)userActivity
  restorationHandler:(void (^)(NSArray* _Nullable))restorationHandler
{
    [AirBridge.deeplink handleUniversalLink:userActivity.webpageURL];

    return YES;
}
func application(_ application: UIApplication,
                 continue userActivity: NSUserActivity,
                 restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool
{
    if let webpageURL = userActivity.webpageURL {      
        AirBridge.deeplink()?.handleUniversalLink(webpageURL)
    }
    
    return true
}

🚧

Links are forwarded to SceneDelegate, not AppDelegate, for projects using SceneDelegate. Please refer to the next section on how to receive deep links through SceneDelegate.

For projects using SceneDelegate

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 universalLinkURL = connectionOptions.userActivities.first?.webpageURL {
            // Universal
            AirBridge.deeplink().handleUniversalLink(universalLinkURL)
        }
        
        // ...
    }
  
      // Receive universal link
    func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
        print(userActivity.webpageURL as Any)
        guard let universalLinkURL = userActivity.webpageURL else {
            return
        }
        
        AirBridge.deeplink().handleUniversalLink(universalLinkURL)
        // ...
    }
  
    // Receive scheme link
    func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        guard let schemeLinkURL = URLContexts.first?.url else {
             return
        }
        
        AirBridge.deeplink().handleURLSchemeDeeplink(schemeLinkURL)
        // ...
    }
}

Deep link Callback Setting

  1. Open ios/[Project file]/AppDelegate.
  2. 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
        // 딥링크로 앱이 열리는 경우 작동할 코드
        // Airbridge 를 통한 Deeplink = YOUR_SCHEME://...
        NSLog("DeeplinkCallback : %@", deeplink)
    })
    
    return true
}

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://....

Custom Domain Setting (Optional)

If you are using a custom domain as an Airbridge tracking link, follow the below steps. (Replace example.com with custom domain)

  1. Go to "Xcode → Project file → Signing & Capabilities → Associated Domains".
  2. Click "+" button and add applinks:example.com.
  3. Open info.plist.
  4. Add the following value.
955955

Test Deep Link

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://)

  1. Click deep link
  2. See if the deep link event appears at "Airbridge dashboard → Raw Data → App Real-time Logs"



User Setup


User Identifier Setup

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:@"[email protected]"];
[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("[email protected]")
AirBridge.state()?.setUserPhone("(123)123-1234")

// 입력된 dictionary 로 user alias 가 교체됩니다.
AirBridge.state()?.setUserAlias(["key": "value"])
// 기존의 user alias 에 해당 key, value 가 추가됩니다.
AirBridge.state()?.addUserAlias(withKey: "key", value: "value")

Name

Description

Limitations

ID

User ID

Email

User Email

Hashed by default
(SHA256, can be disabled)

Phone

User phone number

Hashed by default
(SHA256, can be disabled)

Alias

User alias

  • Maximum 10 aliases
  • key type is NSString, maximum 128 characters
  • key must satisfy ^[a-z_][a-z0-9_]*$ regex
  • value type is NSString, maximum 1024 characters

User Attributes Setup

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"];
// 입력된 dictionary 로 user attributes 가 교체됩니다.
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
  • key type is NSString, maximum 128 characters
  • key must satisfy ^[a-z_][a-z0-9_]*$ regex
  • value type is NSString or NSNumber
  • Maximum 1024 characters for NSString type

Test User Information Setup

Make sure that your user information settings are being properly sent through the SDK.

  1. Configure user identifier information.
  2. Send an event using the SDK.
  3. Click the event at "Airbridge dashboard → Raw Data → App Real-time Logs"
  4. Check if the user information is correctly sent under the user block.



Event Setup


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.


Sending Events

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)



Standard Events

Send standard user events with the SDK.

setAction, setLabel, setValue, setCustoms, setSemantics, setSemanticAttributes can also be used when sending standard events.

User Sign Up

#import <AirBridge/ABUser.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>

ABUser* user = [[ABUser alloc] init];
user.ID = @"personID";
user.email = @"[email protected]";
user.phone = @"1(123)123-1234";
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 = "personID"
user.email = "[email protected]"
user.phone = "(123)123-1234"
user.attributes = [
    "key": "value" as NSObject,
]
user.alias = [
    "key": "value",
]

AirBridge.state().setUser(user)

let event = ABInAppEvent()
event?.setCategory(ABCategory.signUp)
event?.send()

User Sign In

#import <AirBridge/ABUser.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>

ABUser* user = [[ABUser alloc] init];
user.ID = @"personID";
user.email = @"[email protected]";
user.phone = @"1(123)123-1234)";
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 = "personID"
user.email = "[email protected]"
user.phone = "(123)123-1234"
user.attributes = [
    "key": "value" as NSObject,
]
user.alias = [
    "key": "value",
]

AirBridge.state().setUser(user)

let event = ABInAppEvent()
event?.setCategory(ABCategory.signIn)
event?.send()

User Sign Out

#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())

View Home Screen

#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()

View Product Detail

#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;

ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.viewProductDetail];
[event setSemantics:@{
    ABSemanticsKey.products: @[product1.toDictionary],
}];

[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 event = ABInAppEvent()
event?.setCategory(ABCategory.viewProductDetail)
event?.setSemantics([
    ABSemanticsKey.products: [
        product1.toDictionary(),
    ],
])
event?.send()

View Product List

#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.viewProductList];
[event setSemantics:@{
    ABSemanticsKey.products: @[
        product1.toDictionary,
        product2.toDictionary,
    ],
    ABSemanticsKey.productListID: @"listID",
}];

[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.viewProductList)
event?.setSemantics([
    ABSemanticsKey.products: [
        product1.toDictionary(),
        product2.toDictionary(),
    ],
    ABSemanticsKey.productListID: "productListID",
])
event?.send()

View Search Result

#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.viewSearchResult];
[event setSemantics:@{
    ABSemanticsKey.products: @[
        product1.toDictionary,
        product2.toDictionary,
    ],
    ABSemanticsKey.query: @"query",
}];

[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.viewSearchResult)
event?.setSemantics([
    ABSemanticsKey.products: [
        product1.toDictionary(),
        product2.toDictionary(),
    ],
    ABSemanticsKey.query: "query",
])
event?.send()

Add to Cart

#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.addToCart];
[event setSemantics:@{
    ABSemanticsKey.products: @[
        product1.toDictionary,
        product2.toDictionary,
    ],
    ABSemanticsKey.cartID: @"cartID",
    ABSemanticsKey.currency: @"currency",
    ABSemanticsKey.totalValue: @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.addToCart)
event?.setSemantics([
    ABSemanticsKey.products: [
        product1.toDictionary(),
        product2.toDictionary(),
    ],
    ABSemanticsKey.cartID: "cartID",
    ABSemanticsKey.totalValue: 300,
    ABSemanticsKey.currency: "KRW",
])
event?.send()

Order Complete

#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.totalValue: @300,
    ABSemanticsKey.inAppPurchased: @YES,
}];

[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.totalValue: 300,
    ABSemanticsKey.currency: "KRW",
    ABSemanticsKey.inAppPurchased: true,
])
event?.send()

Test Event Transmission

Make sure that the events are being properly sent through the SDK.

  1. Send an event with the SDK.
  2. Check if the event shows up at "Airbridge dashboard → Raw Data → App Real-time Logs".



Advanced Setup


Hash User Information

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)

Session Timeout

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_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
AirBridge.setSessionTimeout(1000 * 60 * 5)

AirBridge.getInstance("YOUR_APP_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)

Privacy Protection

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_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];

[AirBridge startTracking];
AirBridge.setAutoStartTrackingEnabled(false)

AirBridge.getInstance("YOUR_APP_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)

AirBridge.startTracking()

Track Airbridge Links Only

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)

Track Facebook Deferred App Links

The Airbridge SDK can track Facebook deferred App Links through the following settings.

  1. Install the Facebook SDK: https://developers.facebook.com/docs/ios/getting-started.
  2. Open ios/[Project name]/AppDelegate.
  3. Set setIsFacebookDeferredAppLinkEnabled to YES (true) at the beginning of the code that initializes the Airbridge SDK.
[AirBridge setIsFacebookDeferredAppLinkEnabled:YES];

[AirBridge getInstance:@"YOUR_APP_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
AirBridge.setIsFacebookDeferredAppLinkEnabled(true)

AirBridge.getInstance("YOUR_APP_TOKEN", appName: "YOUR_APP_NAME", withLaunchOptions: launchOptions)

Add Device Alias

Another ID of device can be inserted to SDK.

[AirBridge.state setDeviceAlias:@{@"key": @"value"}];
[AirBridge.state addDeviceAliasWithKey:@"key" value:@"value"];
AirBridge.state()?.setDeviceAlias(["key": "value"])
AirBridge.state()?.addDeviceAlias(withKey: "key", value: "value")

Name

Description

Limits

Alias

Device alias

  • Maximum 10 aliases
  • key is maximum 128 characters
  • key must satisfy ^[a-z_][a-z0-9_]*$ regex
  • value type is String
  • value is maximum 1024 characters

Track Uninstall Event

Please refer to this page for more information on app uninstallation tracking.


Track Push Notification Deep Links

Use handleURLSchemeDeeplink 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) {
        NSURL* url = // deeplink of push notification's payload
        
        [AirBridge.deeplink handleURLSchemeDeeplink:url];
    }
}

- (void)userNotificationCenter:(UNUserNotificationCenter *)center 
didReceiveNotificationResponse:(UNNotificationResponse *)response 
         withCompletionHandler:(void (^)(void))completionHandler API_AVAILABLE(ios(10.0)) 
{
    if (UIApplication.sharedApplication.applicationState == UIApplicationStateInactive
        && [response.actionIdentifier isEqual:UNNotificationDefaultActionIdentifier])
    {
        NSURL* url = // deeplink of push notification's payload
        
        [AirBridge.deeplink handleURLSchemeDeeplink:url];
    }
}
func application(_ application: UIApplication, 
                 didReceiveRemoteNotification userInfo: [AnyHashable : Any], 
                 fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) 
{
    if UIApplication.shared.applicationState == .inactive {
        let url = // 푸시 알림 페이로드의 딥링크
            
        AirBridge.deeplink()?.handleURLSchemeDeeplink(url)
    }
}

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, 
                            didReceive response: UNNotificationResponse, withCompletionHandler 
                            completionHandler: @escaping () -> Void) 
{
    if UIApplication.shared.applicationState == .inactive,
       response.actionIdentifier == UNNotificationDefaultActionIdentifier
    {
        let url = // 푸시 알림 페이로드의 딥링크
            
        AirBridge.deeplink()?.handleURLSchemeDeeplink(url)
    }
}

Track Authorize Timeout

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 = 120 * 1000;
AirBridge.setting.isRestartTrackingAuthorizeTimeout = NO;

[AirBridge getInstance:@"YOUR_APP_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
AirBridge.setting()?.trackingAuthorizeTimeout = 120 * 1000
AirBridge.setting()?.isRestartTrackingAuthorizeTimeout = false

AirBridge.getInstance("YOUR_APP_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)

Event Buffer Limit

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)

Settings are applied after the next SDK initialization.



Hybrid Application


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.

❗️

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.


Send WebView Environment Events

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".



Troubleshooting


Webcredentials

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.deeplink.page.

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

  1. Go to "Xcode → Project file → Signing & Capabilities → Associated Domains".
  2. Click "+" and add webcredentials:example.com.