Attention
Due to known issues in the Airbridge SDK versions earlier than v1.35.1, we advise installing the Airbridge SDK v.1.35.1 or later.
Create a Podfile
file with the below commands.
cd path/to/project
touch Podfile
Edit the Podfile
as below.
target '[Project Name]' do
pod 'AirBridge', '1.40.0'
end
To install the Airbridge iOS SDK version 1.18.0 or later, CocoaPods version 1.11.0 or later is required.
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 Airbridge iOS SDK v1.23.0 and later versions can be installed using the SPM.
Navigate to [File]>[Add Packages] in Xcode.
Search for "https://github.com/ab180/airbridge-ios-sdk-deploy" in the "Add Packages" window. Select the version you want to install and click Add Package.
Select Target and click Add Package.
AirBridge will show under "Package Dependencies" if the SDK is properly installed.
Download the AirBridge.xcframework
.
Navigate to [Xcode]>[Project file]>[General]>[Frameworks, Libraries, and Embedded Content] and click +.
Click Add Other.. → Add Files.. at the bottom right.
Add the AirBridge.xcframework
folder in the file downloaded in Step 1.
Set AirBridge.xcframework
to "Embed & Sign."
Click [Xcode]>[Project file]>[General]>[Frameworks, Libraries, and Embedded Content] and click +.
Add the frameworks in the table below.
Set the frameworks as "Do not Embed."
Go to [Xcode]>[Project file]>[Build Phase]>[Link Binary with Libraries].
Set the status of the framework below to Optional
.
Framework | Description |
---|---|
AdSupport.framework | Used to collect IDFA. |
CoreTelephony.framework | Used to collect the carrier information. |
StoreKit.framework | Used to collect the SKAdNetwork information. |
AppTrackingTransparency.framework | Used to collect the user's consent status. |
AdServices.framework | Used to collect Apple Search Ads attribution information. (iOS 14.3+) |
Initialize the SDK by adding the 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 SwiftUI
where AppDelegate
doesn't exist, initialize the SDK through the App
class with @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()
}
}
}
The YOUR_APP_NAME and YOUR_APP_SDK_TOKEN can be found on the [Settings]>[Tokens] page in the Airbridge dashboard.
To use the SDK, you must agree to the "IDFA terms and conditions" when publishing your app to the App Store. Refer to the table below to fill out the form.
Question and Checkboxes | Action |
---|---|
Does this app use the Advertising Identifier (IDFA)? | Yes |
Serve advertisements within the app | Don't 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 |
After completing the Airbridge iOS SDK setup, you can test whether it works properly by following the methods below.
Install and open the app on a test device.
Navigate to [Raw Data]>[App Real-time Logs] in the Airbridge dashboard.
Enter the IDFA of the test device into the search bar to find it in the logs.
It may take up to 5 minutes for the logs to be visible in the dashboard.
The logs will be printed to Xcode if you insert the following at the beginning of the SDK initialization code 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 must be entered on the [Tracking Link]>[Deep Links] page in the Airbridge dashboard.
iOS URI Scheme
iOS App ID
Enter the URI scheme into the iOS URI Scheme field, including ://
.
Attention
To redirect users as intended, submit the URI scheme differently for the production app and the development app.
Go to Identifiers
at https://developer.apple.com/account/resources.
Click the identifier of the app that you want to track.
Copy the identifier information and paste it to the iOS App ID field in the following format.
App ID Prefix
+ .
+ Bundle ID
(Example: 9JA89QQLNQ.com.apple.wwdc
)
Go to [Xcode]>[Project file]>[Info]>[URL Types].
From the Airbridge dashboard, copy "iOS URI Scheme" and paste it to the URL Schemes field in Xcode. Make sure not to 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 on the [Settings]>[Token] page in the Airbridge dashboard.
Refer to Troubleshooting → Webcredentials if you want to use the autofill feature.
For apps that support iOS 12 and earlier, events are usually sent through the application(_:open:options:)
method in AppDelegate
.
Open ios/[Project name]/AppDelegate
.
Call the handleURLSchemeDeeplink
function at the top of the below function to pass the deep link information to the SDK when the app is opened with a scheme.
- (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
}
Call the handleUserActivity
function at the top of the below function to pass the deep link information to the SDK when the app is opened with a Universal Link.
- (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
When using
SceneDelegate
, the deep link is passed toSceneDelegate
instead ofAppDelegate
. Refer to the next section on how to receive the deep link inSceneDelegate
.
For apps that support iOS 13 and later, deep links are passed to the following methods.
When the app was loaded from a "Not running" status: scene(_:willConnectTo:options:)
In 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 are passed to onOpenURL
. Add this method to the App class with @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 you are using
SwiftUI
withSceneDelegate
,onOpenUrl
cannot be used. In such a case, refer to this section.
Open ios/[Project file]/AppDelegate
.
Use the setDeeplinkCallback
function to set up the callback that should be called when the app 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) {
// Code to run when opening app with a deep link
// 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
}
If you are not using AppDelegate
or SceneDelegate
, add the following method to the App
class with @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()
}
}
}
For Airbridge iOS SDK v1.10.0 to 1.10.9: The Airbridge deep link is sent in the format of https://YOUR_APP_NAME.airbridge.io/...
.
For Airbridge
iOS SDK v.1.20.0 to v1.9.10: The Airbridge deep link is sent in the format of either https://YOUR_APP_NAME.airbridge.io/...
or YOUR_SCHEME://...
.
When setting up a deep link callback, information about deferred deep links will also be sent through that deep link callback. Refer to "Set up deep link callback" to set up deferred deep link callbacks.
The deferred deep link callback is sent only once when the app is installed.
Check whether the app opens and the deep link event is sent when the Airbridge deep link is clicked on. The Airbridge deep link should follow the YOUR_SCHEME://...
format. Your_Scheme
is the iOS URI Scheme entered in your Airbridge dashboard.
Click the deep link.
Check whether the deep link event appears on the [Raw Data]>[App Real-time Logs] page in the Airbridge dashboard.
You can set up the SDK so that once a user identifier is sent to the SDK, all events collected thereafter contain the same user identifier.
[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 collected for a more accurate multi-touch attribution and in-depth data analysis.
// 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 |
Check whether the user data setup has been successfully completed by following the steps below.
Complete the user setup.
Send an event through the SDK.
Navigate to [Raw Data]>[App Real-time Logs] in the Airbridge dashboard, find the event sent, and check whether the user data is included under the user
block in the JSON.
Set up the Airbridge SDK to collect device alias when collecting events. The alias won't be deleted even after the user closes the app unless the user deletes the app.
[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 |
---|---|
| Adds the key-value pair to the device identifier. |
| Deletes the device alias of the key. If there is no identifier, no action is executed. |
| Deletes all device aliases. |
When important user actions occur, those actions can be collected as in-app events.
Attention
The
setCategory
function must be called to send events.
You can send in-app events through the SDK to Airbridge for ad performance measurement.
#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) |
#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()
Send an event through the SDK and check whether the event is available in the Airbridge dashboard.
Send an event through the SDK.
Navigate to [Raw Data]>[App Real-time Logs] in the Airbridge dashboard and search for the event.
Depending on policies and environments, restrictions on collecting device IDs like GAID and IDFA may be required. When installing the Restricted SDK version, the device IDs are not collected. The Restricted SDK is supported in v1.34.9 and later.
1. Create a 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
To install the Airbridge iOS SDK version 1.18.0 or later, CocoaPods version 1.11.0 or later is required.
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
With the SDK Signature, you can ensure SDK spoofing prevention and use verified events for ad performance measurement. Call the setSDKSignatureSecret
function above the 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.
By default, the user email and phone number information is hashed using SHA256 before being sent to Airbridge.
To disable hashing, call the setIsUserInfoHashed
function at the beginning of the SDK initialization code.
// 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)
You can set up the session timeout by calling the setSessionTimeout
function at the beginning of the SDK initialization code.
Session timeout is in milliseconds, and the value 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)
The opt-in policy requires user consent before using user data.
Use the method below for collecting and transmitting data after obtaining consent for personal data tracking from users, especially when GDPR or CCPA applies.
If the autoStartTrackingEnabled
function is set to false
before the SDK initialization code, events are not sent before the startTracking
function is called.
For example, if a lifecycle event such as Deeplink Open occur while the app is not opened, and this event is sent before the startTracking
function is called, the event may not be collected.
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
The instructions below are optional. Proceed only if necessary.
The opt-out policy allows the use of user information until the user explicitly declines.
After setting the setAutoStartTrackingEnabled
function to true
, call the stopTracking
function at the point where event data cannot be collected. From the moment the stopTracking
function is called, the SDK will stop collecting events.
#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()
Set the setIsTrackAirbridgeDeeplinkOnly
function to true
at the beginning of the SDK initialization code so that only Airbridge deep links are collected.
// 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)
Follow the steps below to collect Facebook deferred app links through the SDK.
Install the Facebook SDK by following this Facebook document.
Open ios/[Project name]/AppDelegate
.
Call the setIsFacebookDeferredAppLinkEnable
at the beginning of the SDK initialization code. When isFacebookDeferredAppLinkEnabled
is set to YES
(true
) and the Facebook SDK is installed, the SDK collects the Facebook deferred app link.
[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)
Airbridge sends a silent push daily between 3:00 PM and 4:00 PM (UTC) to users whose app event has been collected at least once in the last 6 months to check for uninstalls. Uninstall events can be monitored through Airbridge reports and raw data export files.
Refer to the article below for the detailed setup instructions.
When a user clicks a push notification, the handleNotificationDeeplink
function should be called to pass the deep link in the push notification payload to the SDK.
- (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)
}
}
In iOS 14.5+, the IDFA can only be collected if users consent to data tracking via the App Tracking Transparency (ATT) prompt using the AppTrackingTransparency.framework.
if (@available(iOS 14, *)) {
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
NSLog(@"ATTrackingManagerAuthorizationStatus: %lu", (unsigned long)status);
}];
}
if #available(iOS 14, *) {
ATTrackingManager.requestTrackingAuthorization { status in
print(status.rawValue)
}
}
When using the AppTrackingTransparency.framework to display the ATT prompt to the user, the IDFA is not collected when the install event occurs because the ATT prompt only appears after the user installs the app.
By calling the trackingAuthorizeTimeout
function before the SDK initialization code, the sending of the install event will be delayed for the set timeout period to wait for the user to finish responding to the ATT prompt.
trackingAuthorizeTimeout
is in milliseconds.
The sending of the Install event can be delayed for as long as the trackingAuthorizeTimeout
period.
The trackingAuthorizeTimeout
is initialized every time the app is relaunched.
When the user finishes responding to the ATT prompt, A deferred deep link is sent to the callback.
By default, the trackingAuthorizeTimeout
is initialized every time the app is relaunched. To prevent this, set isRestartTrackingAuthorizeTimeout
to false
.
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)
Attention
For iOS SDK v.1.32.1 and later, the
trackingAuthorizeTimeout
is 30 seconds by default. To optimize user experience, make sure to configure the value to a sufficient time period.
When an event transmission failure occurs, the Airbridge SDK will store the event and retry later. The following settings will allow you to limit the storage used for such events. The new settings will apply starting from the next SDK initialization.
// 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)
You can configure the event transmission cycle so that when the event transmission succeeds once, the next event transmission will take place in the next cycle. The default value is set to 0 milliseconds.
// 이벤트 전송 주기 (Millisecond 단위)
[AirBridge.setting setEventTransmitInterval:newValue]
// 이벤트 전송 주기 (Millisecond 단위)
AirBridge.setting().setEventTransmitInterval(newValue)
Clear the device's internal database of unprocessed events that have not been sent to Airbridge.
// 활성화
Airbridge.setResetEventBufferEnabled(true)
// 비활성화
Airbridge.setResetEventBufferEnabled(false)
Attention
The code above must be run before Airbridge starts tracking. If
autoStartTracking
is set totrue
, the code must be run beforegetInstance
, and ifautoStartTracking
is set tofalse
, the code must be run beforestartTracking
. If not, the function won't work.
Attention
When you set up the Airbridge iOS SDK v1.24.0 or later to use tracking links within apps, every time a tracking link is used within the app, Deeplink Pageviews are aggregated as Target Events. The deep link performance may be affected when Deeplink Pageviews occur frequently right after Deeplink Opens.
The attribution window for Deeplink Pageviews is set to 3 days by default. If you want to change the attribution window for Deeplink Pageviews, contact your Airbridge CSM. If you don't have a dedicated CSM, contact the Airbridge Help Center.
You can use tracking links within the app. Note that custom domain tracking links with custom short IDs cannot don't function within the app. Use the method below to redirect users to specific in-app locations without sending them to an external browser.
Airbridge.placement().click("https://abr.ge/~~~")
Airbridge.placement().impression("https://abr.ge/~~~")
When a user clicks on the tracking link within the app, the Airbridge.click
function is called. A click event is collected, and the user is redirected to the configured app or web fallback path.
When a user engages with a tracking link within the app, the Airbridge.click
function is called. An impression event is collected.
To get the attribution result from the Airbridge iOS SDK, the callback closer must be passed to the attributionCallback
.
The attribution result callback is provided only once after the app install.
AirBridge.setting().attributionCallback = { (attribution: [String : String]) in
// Process attribution data...
}
[AirBridge.setting setAttributionCallback:^(NSDictionary<NSString *,NSString *> * _Nonnull attribution) {
// Process attribution data...
}];
The table below lists the 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 an event is unattributed, meaning that there is no attribution result, you will get the following response.
{
"attributedChannel": "unattributed"
}
Guidelines for using attribution result data
Attribution data is forwarded within 40 seconds of SDK initialization.
If the app is closed and the attribution data cannot be received, the attribution data is forwarded within 40 seconds when the app is opened again.
On very rare occasions, it could take up to 5 minutes for the attribution data to be received.
When the attribution data does not exist
The attribution data will be sent when the app is opened again after at least three hours have passed since the SDK was initialized.
Note that it is not recommended to use the attribution data for real-time processing.
Guidelines for using attribution result data
Attribution data is forwarded within 40 seconds of SDK initialization.
If the app is closed and the attribution data cannot be received, the attribution data is forwarded within 40 seconds when the app is opened again.
On very rare occasions, it could take up to 5 minutes for the attribution data to be received.
When the attribution data does not exist
The attribution data will be sent when the app is opened again after at least three hours have passed since the SDK was initialized.
Note that it is not recommended to use the attribution data for real-time processing.
The following code allows you to collect lifecycle events (ORGANIC_REOPEN
, FOREGROUND
) within the session timeframe.
[AirBridge.setting setTrackInSessionLifeCycleEventEnabled:YES];
AirBridge.setting().setTrackInSessionLifeCycleEventEnabled(true)
All Airbridge functions can be turned off using the following method.
// 활성화
Airbridge.setSDKEnabled(true)
// 비활성화
Airbridge.setSDKEnabled(false)
Attention
The above function must be run before the initialization code (
getInstance
). If not, the function won't work.
Initialize the SDK using the viewDidLoad
function in the iOS Extension and collect events using the functions listed here.
override func viewDidLoad() {
super.viewDidLoad()
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)
}
Attention
The following limitations exist when utilizing the Airbridge SDK in iOS Extensions.
In iOS Extensions, lifecycle events such as Install, Open, Deeplink Open, and Foreground events are not collected.
If event transmission from the iOS Extension is abruptly terminated, it will resume later when the Extension is launched again. The event transmission is not attempted when the app is launched.
SKAN measurement is not recommended when using the Airbridge SDK in the iOS Extension, as the conversion value measurement may not work correctly.
To comply with the Digital Markets Act (DMA), you must pass user consent data to Airbridge. For more information about the DMA and whether it applies to your service, see the Airbridge user guide.
If you are in the European Economic Area (EEA), you must always pass User Response information to 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
), confirm whether the consent values have already been 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 consent 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 passed to Airbridge. The eea
value is neither the response from the user nor a value automatically filled in by Airbridge. Advertisers should determine the eea
value based on whether the user is in the EEA region and whether the DMA applies or not.
Field Name in Airbridge |
Field Name in Google |
Description |
---|---|---|
<string> |
| Indicates whether the user is in the EEA region and whether the DMA applies or not. The value is neither the response from the user nor a value automatically filled in by Airbridge. Determine the value based on where 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 pass the user data used for advertising to Google. Values other than - - |
3. Initialize the Airbridge SDK and share the consent values with Airbridge before collecting the end user’s personal data.
Attention
Take note of the following items.
Use the field names specified by Airbridge:
eea
,adPersonalization
, andadUserData
Input
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];
}
Attention
Note that to utilize this feature, both SDKs must be installed: the Android SDK on the mobile native environment and the WebView SDK on the WebView environment's website.
The iOS SDK can handle event transmission occurring within the in-app website of a hybrid app instead of the Web SDK installed on the website.
Refer to the configuration below.
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)
You can find the YOUR_WEB_TOKEN
on the [Settings]>[Tokens] page in your Airbridge dashboard.
Users may see the domain of passwords stored with the Password AutoFill feature as airbridge.io or abr.ge. If you want to change the domain to store the password, follow the steps below.
Host the JSON below at https://example.com/.well-known/apple-app-site-association
. Your prepared domain should be entered instead of example.com
.
{
"webcredentials": {
"apps": ["TEAM_ID.APP_BUNDLE_ID"]
}
}
Example: 9JA89QQLNQ.com.apple.wwdc
Navigate to [Xcode]>[Project File]>[Signing & Capabilities]>[Associated Domains].
Click +
and add webcredentials:example.com.
Airbridge iOS SDK does not support Bitcode from version 1.28.0. Note that Bitcode has been deprecated from Xcode 14. If you use Bitcode in an App project, you may encounter the following compile errors.
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)
To solve this issue, you need to add the following to the Podfile.
installer.pods_project.targets.each do |target|
target.build_configurations.each do |configuration|
configuration.build_settings['ENABLE_BITCODE'] = 'NO'
end
end
Or you may set the ENABLE_BITCODE
to No
.
Note that Bitcode has been deprecated, and the App Store automatically deletes the Bitcode when .ipa files using Bitcode are submitted.
The Airbridge iOS SDK does not support Xcode 13 and iOS 9 or 10 starting from version 1.28.0.
If you need to use Xcode 13, use Airbridge iOS SDK versions 1.27.0 or earlier.
The Airbridge iOS SDK utilizes several built-in iOS frameworks. Among them, AdServices requires the iOS version 14.2 or later. However, the Swift Package Manager has a feature that automatically links a framework as Optional
if its minimum OS version is higher than the Target's minimum OS version. In contrast, when using Tuist fetch—which only retrieves metadata instead of utilizing Swift Package Manager—the framework is linked to Required
, leading to this issue. You can find the relevant Tuist code here.
In this case, you can resolve the problem by installing the SDK using the method "Xcode Native Package Manager Support" provided by Tuist, or you can simply download AirBridge.xcframework and add it to the SDK.
.xcframework(path: "${YOUR_PATH}/AirBridge.xcframework")
.sdk(name: "AdSupport", type: .framework, status: .optional)
.sdk(name: "iAd", type: .framework, status: .optional)
.sdk(name: "AdServices", type: .framework, status: .optional)
.sdk(name: "CoreTelephony", type: .framework, status: .optional)
.sdk(name: "StoreKit", type: .framework, status: .optional)
.sdk(name: "AppTrackingTransparency", type: .framework, status: .optional)
.sdk(name: "WebKit", type: .framework, status: .optional)
When updating the SDK, consider the content regarding versions between the previous version and the later version or your updated version.
For apps registered with Airbridge after November 4, 2023, an issue where the deep link URL provided in the deep link callback was decoded twice from the content entered in the Airbridge dashboard has been resolved. This issue was found in versions 1.34.0 to 1.35.1.
For apps registered with Airbridge after September 4, 2023, the "airbridge_referrer" will no longer be added to the deep link URL provided in the deep link callback and will instead pass it to the information entered in the Airbridge Dashboard.
When updating app from iOS SDK v1.33.0 or earlier to v1.33.0 or later, the last calculated SKAN conversion value will be finalized, and no additional calculation will be processed.
For iOS SDK versions earlier than 1.33.0, the SKAN conversion value is calculated for up to 24 hours.
There is no issue for users who newly install the SDK.
The default setting for trackingAuthorizeTimeout changed from 0 seconds to 30 seconds.
Was this page helpful?