提示
本指南介绍如何安装和设置 iOS SDK(v4)。如需了解旧版本,请参阅 iOS SDK(旧版本)。
您可以通过以下方法安装 Airbridge iOS SDK。安装后,您可以通过 测试 iOS SDK 来检查 SDK 是否正确安装。
1. 请在 Xcode 中导航至 [File]>[Add Packages...]。
2. 请在搜索栏中输入以下地址,并点击 [Add Package]。
3. 请再次点击 [Add Package]。
4. 请在 Xcode 的 [Package Dependencies] 中确认 Airbridge iOS SDK 已成功添加。
注意
在安装 iOS SDK 之前,请导航至 [Xcode]>[YOUR_PROJECT]>[Build Settings],并确保将 User Script Sandboxing 设置为 “No”。更多信息请参阅 CocoaPods 文档。
1. 请使用 brew install cocoapods
安装 CocoaPods。
2. 请使用 pod init
创建 Podfile。
3. 请使用以下代码将 SDK 添加为 Podfile 的依赖项。
target '[Project Name]' do
...
# choose YOUR_VERSION from https://help.airbridge.io/developers/release-note-ios-sdk
# example: pod 'airbridge-ios-sdk', '4.X.X'
pod 'airbridge-ios-sdk', 'YOUR_VERSION'
...
end
4. 在输入 pod install --repo-update
时,安装将开始。
5. 请运行 YOUR_PROJECT.xcworkspace
以确认 Airbridge iOS SDK 成功安装。
注意
您无法使用 Tuist 的 External Dependencies 安装 Airbridge iOS SDK。请确保按照以下步骤安装。
1. 请运行 tuist edit
命令。
2. 请将 remote
添加到 project.packages
。请将 package
添加到 project.targets[...].target.dependencies
中。请参见以下代码:
import ProjectDescription
let project = Project(
packages: [
.remote(
url: "https://github.com/ab180/airbridge-ios-sdk-deployment",
// choose YOUR_VERSION from https://help.airbridge.io/developers/release-note-ios-sdk
// example: requirement: .exact(from: "4.X.X")
requirement: .exact(from: "YOUR_VERSION")
),
...
],
targets: [
.target(
dependencies: [
.package(product: "Airbridge", type: .runtime),
...
]
),
...
],
...
)
3. 请运行 tuist generate
命令。
4. Airbridge 将添加至 Xcode 的 Package Dependencies 中。
1. 请从以下链接下载 Airbridge iOS SDK:
2. 请将 Airbridge.xcframework 添加到 Project 中。请导航至 [Xcode]>[Project File]>[General]>[Frameworks, Libraries, and Embedded Content],并点击 “+”。
3. 请在 [Add Other...] 下点击 “Add Files...”,并选择 Airbridge.xcframework。
4. 请将 Airbridge.xcframework 中的 Embed(嵌入)设置为 Do Not Embed(不嵌入)。
5. 请将 SDK 依赖的 Framework 添加到 Project 中。请导航至 [Xcode]>[Project File]>[General]>[Frameworks, Libraries, and Embedded Content],并点击 “+”。
6. 请添加所有以下 Framework,并将已添加 Framework 的 Embed(嵌入)设置为 Do Not Embed(不嵌入)。请导航至 [Xcode]>[Project File]>[Build Phase]>[Link Binary With Libraries],将 Status(状态)设置为 “Optional(可选)”。
Framework | 说明 |
---|---|
AdSupport.framework | 用于收集 IDFA |
CoreTelephony.framework | 用于收集移动通信运营商信息 |
StoreKit.framework | 用于收集 SKAN 信息 |
AppTrackingTransparency.framework | 用于收集 ATT 同意状态信息 |
AdServices.framework | 用于收集 Apple Ads 归因信息(iOS 14.3+) |
提示
请根据需求选择一般 SDK 或 Restricted SDK, 只能安装其中一个。
根据政策或环境,可能需要对收集 设备 ID(例如 GAID 或 IDFA)进行限制。如果安装 Restricted SDK,Airbridge SDK 不会收集设备 ID。
请按照以下说明安装 Restricted SDK:
1. 请在 Xcode 中导航至 [File]>[Add Packages...]。
2. 请在搜索栏中输入以下地址,并点击 [Add Package]。
3. 请再次点击 [Add Package]。
4. 请在 Xcode 的 [Package Dependencies] 中确认 Airbridge iOS SDK 已成功添加。
注意
在安装 iOS SDK 之前,请导航至 [Xcode]>[YOUR_PROJECT]>[Build Settings],并确保将 User Script Sandboxing 设置为 “No”。更多信息请参阅 CocoaPods 文档。
1. 请使用 brew install cocoapods
安装 CocoaPods。
2. 请使用 pod init
创建 Podfile。
3. 请使用以下代码将 SDK 添加为 Podfile 的依赖项。
target '[Project Name]' do
...
# choose YOUR_VERSION from https://help.airbridge.io/developers/release-note-ios-sdk
# example: pod 'airbridge-ios-sdk-restricted', '4.X.X'
pod 'airbridge-ios-sdk-restricted', 'YOUR_VERSION'
...
end
4. 在输入 pod install --repo-update
时,安装将开始。
5. 请运行 YOUR_PROJECT.xcworkspace
以确认 Airbridge iOS SDK 成功安装。
注意
您无法使用 Tuist 的 External Dependencies 安装 Airbridge iOS SDK。请确保按照以下步骤安装。
1. 请运行 tuist edit
命令。
2. 请将 remote
添加到 project.packages
。请将 package
添加到 project.targets[...].target.dependencies
中。请参见以下代码:
import ProjectDescription
let project = Project(
packages: [
.remote(
url: "https://github.com/ab180/airbridge-ios-sdk-restricted-deployment",
// choose YOUR_VERSION from https://help.airbridge.io/developers/release-note-ios-sdk
// example: requirement: .exact(from: "4.X.X")
requirement: .exact(from: "YOUR_VERSION")
),
...
],
targets: [
.target(
dependencies: [
.package(product: "Airbridge", type: .runtime),
...
]
),
...
],
...
)
3. 请运行 tuist generate
命令。
4. Airbridge 将添加至 Xcode 的 Package Dependencies 中。
1. 请从以下链接下载 Airbridge iOS SDK。
2. 请将 Airbridge.xcframework 添加到 Project 中。请导航至 [Xcode]>[Project File]>[General]>[Frameworks, Libraries, and Embedded Content],并点击 “+”。
3. 请在 [Add Other...] 下点击 “Add Files...”,并选择 Airbridge.xcframework。
4.请将 Airbridge.xcframework 中的 Embed(嵌入)设置为 Do Not Embed(不嵌入)。
5. 请将 SDK 依赖的 Framework 添加到 Project 中。请导航至 [Xcode]>[Project File]>[General]>[Frameworks, Libraries, and Embedded Content],并点击 “+”。
6. 请添加所有以下 Framework,并将已添加 Framework 的 Embed(嵌入)设置为 Do Not Embed(不嵌入)。请导航至 [Xcode]>[Project File]>[Build Phase]>[Link Binary With Libraries],将 Status(状态)设置为 “Optional(可选)”。
Framework | 说明 |
---|---|
CoreTelephony.framework | 用于收集移动通信运营商信息 |
StoreKit.framework | 用于收集 SKAN 信息 |
AdServices.framework | 用于收集 Apple Ads 的归因信息(iOS 14.3+) |
SDK 初始化方法因系统方式而异。SceneDelegate Lifecycle 或 AppDelegate Lifecycle 请参考 AppDelegate,SwiftUI Lifecycle 请参考 SwiftUI。
YOUR_APP_NAME
和 YOUR_APP_SDK_TOKEN
可在 Airbridge 面板的 [设置]>[Token] 获取。
请在 AppDelegate
的 application(_:didFinishLaunchingWithOptions:)
函数顶部调用 Airbridge.initializeSDK
函数。
import UIKit
import Airbridge
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
.build()
Airbridge.initializeSDK(option: option)
return true
}
}
请在 AppDelegate 的 application:didFinishLaunchingWithOptions:
函数顶部调用 Airbridge.initializeSDK
函数。
#import "AppDelegate.h"
#import <Airbridge/Airbridge.h>
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
token:@"YOUR_APP_SDK_TOKEN"];
AirbridgeOption* option = [optionBuilder build];
[Airbridge initializeSDKWithOption:option];
return YES;
}
@end
请在 init
的顶部调用 Airbridge.initializeSDK
函数。
import SwiftUI
import Airbridge
@main
struct ExampleApp: App {
init() {
let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
.build()
Airbridge.initializeSDK(option: option)
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
注意
SwiftUI Lifecycle 方法不提供 ReferrerURL,因此无法使用 Organic Referrer Attribution。即使使用 UIApplicationDelegateAdaptor,在 SwiftUI Lifecycle 方法中也无法使用 Organic Referrer Attribution。
提示
为确保遵守隐私政策所需的功能,应与法律顾问共同审查。
在 iOS 环境中,只有在通过 ATT(App Tracking Transparency,应用跟踪透明度)弹窗征得用户同意后,才能收集 IDFA。
收集安装事件应延迟到用户允许追踪后进行。IDFA 会与安装事件一同收集,因此如果在用户通过 ATT 弹窗允许追踪之前收集安装事件,IDFA 将缺失,影响绩效监测。建议设置足够的延迟时间,以确保 IDFA 被正确收集。
1. 请准备好您将在 ATT 弹窗中使用的文本。
2. 请在 Info.plist
文件的 NSUserTrackingUsageDescription
值中输入准备好的文本。
请导航至 [Xcode]>[YOUR_PROJECT]>[Info]>[Custom iOS Target Properties]。
请将鼠标悬停在 Key 的项目,点击出现的 “+”,并输入 Privacy - Tracking Usage Description
。
请将准备好的 ATT 弹窗文本作为值输入。
1. 请输入 tuist edit 命令。
2. 请在 project.targets[...].infoPlist
的 .extendingDefault
中,作为键输入 NSUserTrackingUsageDescription
,作为值输入准备好的 ATT 弹窗文本。
import ProjectDescription
let project = Project(
targets: [
.target(
infoPlist: .extendingDefault(
with: [
"NSUserTrackingUsageDescription": "YOUR_DESCRIPTION",
...
]
),
...
),
...
]
...
)
3. 请设置 ATT 弹窗的弹出时间。
请在计划弹出 ATT 弹窗的时间调用 ATTrackingManager.requestTrackingAuthorization
函数。
import AppTrackingTransparency
...
ATTrackingManager.requestTrackingAuthorization { _ in }
#import <AppTrackingTransparency/AppTrackingTransparency.h>
...
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {}];
注意
当调用
ATTrackingManager.requestTrackingAuthorization
函数时,如果 App 不处于 Active 状态,则不会弹出 ATT 弹窗。
App 启用后可立即弹出 ATT 弹窗。
import Airbridge
import AppTrackingTransparency
...
var observer: Any?
...
let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
.build()
Airbridge.initializeSDK(option: option)
...
observer = NotificationCenter.default.addObserver(
forName: UIApplication.didBecomeActiveNotification,
object: nil,
queue: nil
) { [weak self] _ in
if #available(iOS 14, *) {
ATTrackingManager.requestTrackingAuthorization { _ in }
}
if let observer = self?.observer {
NotificationCenter.default.removeObserver(observer)
}
}
#import <Airbridge/Airbridge.h>
#import <AppTrackingTransparency/AppTrackingTransparency.h>
...
id observer;
...
AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
token:@"YOUR_APP_SDK_TOKEN"];
[optionBuilder setAutoDetermineTrackingAuthorizationEnabled:NO];
AirbridgeOption* option = [optionBuilder build];
[Airbridge initializeSDKWithOption:option];
...
__weak typeof(self) weakSelf = self;
observer = [NSNotificationCenter.defaultCenter addObserverForName:UIApplicationDidBecomeActiveNotification
object:nil
queue:nil
usingBlock:^(NSNotification * _Nonnull notification) {
if (@available(iOS 14, *)) {
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {}];
}
if (weakSelf != nil && weakSelf->observer != nil) {
[NSNotificationCenter.defaultCenter removeObserver:observer];
}
}];
import SwiftUI
import Airbridge
import AppTrackingTransparency
@main
struct ExampleApp: App {
var observer: Any?
init() {
let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
.build()
Airbridge.initializeSDK(option: option)
observer = NotificationCenter.default.addObserver(
forName: UIApplication.didBecomeActiveNotification,
object: nil,
queue: nil
) { [weak self] _ in
if #available(iOS 14, *) {
ATTrackingManager.requestTrackingAuthorization { _ in }
}
if let observer = self?.observer {
NotificationCenter.default.removeObserver(observer)
}
}
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
4. 如果未收集到安装事件,Airbridge iOS SDK 会在每次 App 启用时延迟 30 秒尝试收集安装事件,直到用户允许追踪为止。如果用户在决定是否允许追踪之前关闭 App,SDK 将不会收集安装事件,并会在下次启用 App 时重试。
安装事件默认收集延迟时间为 30 秒。您可以使用 setAutoDetermineTrackingAuthorizationTimeout
函数修改此值,最长可达 3600 秒(1 小时)。
import Airbridge
...
let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME",
token: "YOUR_APP_SDK_TOKEN")
.setAutoDetermineTrackingAuthorizationTimeout(second: 30)
.build()
Airbridge.initializeSDK(option: option)
#import <Airbridge/Airbridge.h>
...
AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
token:@"YOUR_APP_SDK_TOKEN"];
[optionBuilder setAutoDetermineTrackingAuthorizationTimeoutWithSecond:30];
AirbridgeOption* option = [optionBuilder build];
[Airbridge initializeSDKWithOption:option];
注意
请确保为延迟收集安装事件预留足够时间。在用户通过 ATT 弹窗允许追踪之前,如果延迟时间到期,SDK 将会收集不包含 IDFA 的安装事件。
提示
此功能并非必需功能,请在设置前确认需求。
Opt-in 政策是指在用户同意之前不使用用户信息。
请将 setAutoStartTrackingEnabled
函数设置为 false
后,在可以收集事件时调用 startTracking
函数。从调用 startTracking
函数的时刻起,才开始收集事件。
import Airbridge
...
let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
.setAutoStartTrackingEnabled(false)
.build()
Airbridge.initializeSDK(option: option)
...
Airbridge.startTracking()
#import <Airbridge/Airbridge.h>
...
AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
token:@"YOUR_APP_SDK_TOKEN"];
[optionBuilder setAutoStartTrackingEnabled:NO];
AirbridgeOption* option = [optionBuilder build];
[Airbridge initializeSDKWithOption:option];
...
[Airbridge startTracking];
提示
此功能并非必需功能,请在设置前确认需求。
Opt-out 政策是指在用户拒绝之前使用用户信息。
将 setAutoStartTrackingEnabled
函数设置为 true
后,在无法再收集事件时调用 stopTracking
函数。从调用 stopTracking
函数的时刻起,将不再收集事件。
import Airbridge
...
let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
.setAutoStartTrackingEnabled(true)
.build()
Airbridge.initializeSDK(option: option)
...
Airbridge.stopTracking()
#import <Airbridge/Airbridge.h>
...
AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
token:@"YOUR_APP_SDK_TOKEN"];
[optionBuilder setAutoStartTrackingEnabled:YES];
AirbridgeOption* option = [optionBuilder build];
[Airbridge initializeSDKWithOption:option];
...
[Airbridge stopTracking];
提示
此功能并非必需功能,请在设置前确认需求。
您可以通过 SDK 签名防止 SDK 伪造 (SDK Spoofing)。
SDK 签名设置需要 SDK 签名凭证。SDK 签名凭证包括 Secret 和 Secret ID。您可以在 Airbridge 面板中获取所需的 SDK 签名凭证。SDK 签名凭证的更多信息,请参阅 本指南。
您可以通过在 SDK 初始化代码之前调用 setSDKSignature
函数来设置 SDK 签名。
import Airbridge
...
let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
.setSDKSignature(
id: "YOUR_SDK_SIGNATURE_SECRET_ID",
secret: "YOUR_SDK_SIGNATURE_SECRET"
)
.build()
Airbridge.initializeSDK(option: option)
#import <Airbridge/Airbridge.h>
...
AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
token:@"YOUR_APP_SDK_TOKEN"];
[optionBuilder setSDKSignatureWithId:@"YOUR_SDK_SIGNATURE_SECRET_ID"
secret:@"YOUR_SDK_SIGNATURE_SECRET"];
AirbridgeOption* option = [optionBuilder build];
[Airbridge initializeSDKWithOption:option];
SDK 设置需要以下信息:
YOUR_APP_NAME
:Airbridge App 名称,可以在 Airbridge 面板的 [设置]>[Token] 中获取。
YOUR_APP_SDK_TOKEN
:Android SDK Token,可以在 Airbridge 面板的 [设置]>[Token] 中获取。
YOUR_SDK_SIGNATURE_SECRET
:Secret,可以在 Airbridge 面板的 [规则管理]>[作弊验证规则]>[SDK 签名] 中获取。
YOUR_SDK_SIGNATURE_SECRET_ID
:Secret ID,可以在 Airbridge 面板的 [规则管理]>[作弊验证规则]>[SDK 签名] 中获取。
您可以通过设置深度链接,将点击包含追踪链接的广告的用户跳转至 App 的特定页面。此外,还可以基于追踪链接收集的信息,在 Airbridge 面板查看通过深度链接产生的绩效。
Airbridge 会根据环境自动选用最适合的 Airbridge 深度链接来实现用户跳转。用于实现用户跳转的链接被称为 URI Scheme 深度链接。
示例:
Airbridge 深度链接:https://YOUR_APP_NAME.airbridge.io/~~~
URI Scheme 深度链接:YOUR_SCHEME://product/12345
当 App 已安装时,用户点击追踪链接后,App 将通过 Airbridge 深度链接打开。随后,Airbridge SDK 会将该 Airbridge 深度链接转换为追踪链接中配置的 URI Scheme 深度链接,并将转换后的 URI Scheme 深度链接传递给 App。
当 App 未安装时,用户点击追踪链接后,Airbridge 会保存深度链接信息。用户被发送至应用商店或网站安装并打开 App 后,Airbridge SDK 会将保存的 Airbridge 深度链接转换为 URI Scheme 深度链接,并将转换后的 URI Scheme 深度链接传递给 App。
请按照以下步骤设置深度链接。请准备在 Airbridge 面板中注册的深度链接信息和用户跳转目的地的 App 内页面地址。
首先,请在 Airbridge 面板注册深度链接信息。
请前往 [追踪链接]>[深度链接] 注册以下信息:
iOS URI Scheme:根据 iOS URI Scheme,将 Airbridge 深度链接转换为 URI Scheme 深度链接。URI Scheme 需要此信息。
iOS App ID:根据 iOS App ID,为 Airbridge 深度链接设置 Universal Link 域名。Universal Link 需要此信息。
注意
为确保正确的用户跳转,请为正式版 App 和 开发用 App 注册不同的 iOS URI Scheme 和 iOS App ID。
请按照以下步骤将上述信息注册至 Airbridge 面板。
1. 请前往 [追踪链接]>[深度链接]。
2. 请在 [iOS URI Scheme] 中输入 iOS URI Scheme,该 URI Scheme 必须与 ://
一起输入。例如,如果 iOS URI Scheme 是 demo
,则输入 demo://
。
3. 请在 Apple Developer Dashboard,进入您要设置深度链接的 App 的 [Identifier] 页面,获取 App ID Prefix 和 Bundle ID。
4. iOS App ID 的格式为 App ID Prefix
+ .
+ Bundle ID
。请在 Airbridge 面板 [追踪链接]>[深度链接]>[iOS App ID] 中输入 iOS App ID。
例如,如果 App ID Prefix 是 prefix,Bundle ID 是 example,则 iOS App ID 为 prefix.example
。
在 Airbridge 面板注册深度链接信息后,需要在 App 中设置深度链接。请根据 App 的系统方式,查看相应的深度链接设置流程。
请进行设置启用以下功能:
使用 Airbridge 深度链接启用 App
在 App 收集 Airbridge 深度链接事件
使用 Airbridge 深度链接实现用户跳转
当用户点击追踪链接时,App 应通过 Airbridge 深度链接启用。
1. 需要在 App 进行 Airbridge 深度链接的 URI Scheme 深度链接设置。请在 Xcode 中导航至 [YOUR_PROJECT]>[Info]>[URL Types]。
2. 请点击 “+”,并在 URL Schemes 中输入已在 Airbridge 面板中注册的 iOS URI Scheme。
注意
必须输入不包括
://
的 iOS URI Scheme。
3. 需要在 App 进行 Airbridge 深度链接的 Universal Link 设置。请在 Xcode 中导航至 [YOUR_PROJECT]>[Signing & Capabilities]。
4. 请点击 “+ Capability” 以添加 Associated Domains。
5. 请将 applinks:YOUR_APP_NAME.airbridge.io
和 applinks:YOUR_APP_NAME.abr.ge
添加到 Associated Domains。YOUR_APP_NAME
是 Airbridge App 名称。
注意
如果您正在使用或计划使用 Password AutoFill 功能,则必须添加 Webcredentials 域名。否则用户可能会看到通过 Password AutoFill 功能保存的密码域名显示为 airbridge.io 或 abr.ge。
更多信息请参阅 本指南。
注意
在 iOS,无法自动收集深度链接事件。必须使用
Airbridge.trackDeeplink
函数将深度链接事件传递给 Airbridge SDK。
为了收集深度链接事件,必须将深度链接事件传递给 Airbridge SDK。当 App 通过深度链接启用时,请在调用的 OS 回调顶部调用 Airbridge.trackDeeplink
函数。
import Airbridge
...
Airbridge.trackDeeplink(url: url)
Airbridge.trackDeeplink(userActivity: userActivity)
#import <Airbridge/Airbridge.h>
...
[Airbridge trackDeeplinkWithUrl:url];
[Airbridge trackDeeplinkWithUserActivity:userActivity];
请根据 App 状态进行设置:
1. 当已关闭的 App 通过 URI Scheme 深度链接或 Universal Link 重新启用时,请在调用的函数中调用 Airbridge.trackDeeplink
函数。
import Airbridge
...
// when terminated app is opened with scheme deeplink or universal links
func scene(
_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions
) {
// when app is opened with scheme deeplink
if let url = connectionOptions.urlContexts.first?.url {
// track deeplink
Airbridge.trackDeeplink(url: url)
}
// when app is opened with universal links
else if let userActivity = connectionOptions.userActivities.first {
// track deeplink
Airbridge.trackDeeplink(userActivity: userActivity)
}
}
#import <Airbridge/Airbridge.h>
...
// when terminated app is opened with scheme deeplink or universal links
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
// when app is opened with scheme deeplink
NSURL* url = connectionOptions.URLContexts.allObjects.firstObject.URL;
NSUserActivity* userActivity = connectionOptions.userActivities.allObjects.firstObject;
if (url != nil) {
// track deeplink
[Airbridge trackDeeplinkWithUrl:url];
}
else if (userActivity != nil) {
// track deeplink
[Airbridge trackDeeplinkWithUserActivity:userActivity];
}
}
2. 当后台中的 App 通过 URI Scheme 深度链接启用时,请在调用的函数中调用 Airbridge.trackDeeplink
函数。
import Airbridge
...
// when backgrounded app is opened with scheme deeplink
func scene(
_ scene: UIScene,
openURLContexts URLContexts: Set<UIOpenURLContext>
) {
guard let url = URLContexts.first?.url else { return }
// track deeplink
Airbridge.trackDeeplink(url: url)
}
#import <Airbridge/Airbridge.h>
...
// when backgrounded app is opened with scheme deeplink
- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts {
NSURL* url = URLContexts.allObjects.firstObject.URL;
if (url == nil) { return; }
// track deeplink
[Airbridge trackDeeplinkWithUrl:url];
}
3. 当后台中的 App 通过 Universal Link 启用时,请在调用的函数中调用 Airbridge.trackDeeplink
函数。
import Airbridge
...
// when backgrounded app is opened with universal links
func scene(
_ scene: UIScene,
continue userActivity: NSUserActivity
) {
// track deeplink
Airbridge.trackDeeplink(userActivity: userActivity)
}
// when backgrounded app is opened with universal links
- (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity {
// track deeplink
[Airbridge trackDeeplinkWithUserActivity:userActivity];
}
为确保将用户发送到目标页面,必须使用 Airbridge.handleDeeplink
函数将 Airbridge 深度链接转换为 URI Scheme 深度链接。
import Airbridge
...
// handle deeplink
var isHandled = Airbridge.handleDeeplink(url: url) { url in
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
}
if isHandled { return }
// when app is opened with other deeplink
// use existing logic as it is
...
// handle deeplink
var isHandled = Airbridge.handleDeeplink(userActivity: userActivity) { url in
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
}
if isHandled { return }
// when app is opened with other deeplink
// use existing logic as it is
#import <Airbridge/Airbridge.h>
...
// handle deeplink
BOOL isHandled = [Airbridge handleDeeplinkWithUrl:url onSuccess:^(NSURL* url) {
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
}];
if (isHandled) { return; }
// when app is opened with other deeplink
// use existing logic as it is
...
// handle deeplink
BOOL isHandled = [Airbridge handleDeeplinkWithUserActivity:userActivity onSuccess:^(NSURL* url) {
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
}];
if (isHandled) { return; }
// when app is opened with other deeplink
// use existing logic as it is
Airbridge.handleDeeplink
函数在输入 Airbridge 深度链接时,会返回 true
并通过回调提供 URI Scheme 深度链接。如果不是 Airbridge 深度链接,则返回 false
,且不提供回调。利用此功能,可以分开处理通过 Airbridge 启用的深度链接。
根据系统方式和 App 状态,在通过深度链接启用的 App 调用的 OS 回调中,将 Airbridge.handleDeeplink
函数放置在 Airbridge.trackDeeplink
函数的正下方调用。如有必要,应将现有逻辑一并处理。
1. 请在 SceneDelegate 中实现处理通过 Airbridge 深度链接启用的 App 的函数。
import Foundation
...
// when app is opened with airbridge deeplink
func handleAirbridgeDeeplink(url: URL) {
// show proper content using url (YOUR_SCHEME://...)
}
import Foundation
...
// when app is opened with airbridge deeplink
- (void)handleAirbridgeDeeplink:(NSURL *)url {
// show proper content using url (YOUR_SCHEME://...)
}
2. 当已关闭的 App 通过 URI Scheme 深度链接或 Universal Link 重新启用时,请在调用的函数中调用 Airbridge.handleDeeplink
函数。转换后的 URI Scheme 深度链接将用户发送到预设的目标页面。
import Airbridge
...
// when terminated app is opened with scheme deeplink or universal links
func scene(
_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions
) {
// when app is opened with scheme deeplink
if let url = connectionOptions.urlContexts.first?.url {
// track deeplink
Airbridge.trackDeeplink(url: url)
// handle deeplink
var isHandled = Airbridge.handleDeeplink(url: url) { url in
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
handleAirbridgeDeeplink(url: url)
}
if isHandled { return }
// when app is opened with other deeplink
// use existing logic as it is
}
// when app is opened with universal links
else if let userActivity = connectionOptions.userActivities.first {
// track deeplink
Airbridge.trackDeeplink(userActivity: userActivity)
// handle deeplink
var isHandled = Airbridge.handleDeeplink(userActivity: userActivity) { url in
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
handleAirbridgeDeeplink(url: url)
}
if isHandled { return }
// when app is opened with other deeplink
// use existing logic as it is
}
}
#import <Airbridge/Airbridge.h>
...
// when terminated app is opened with scheme deeplink or universal links
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
// when app is opened with scheme deeplink
NSURL* url = connectionOptions.URLContexts.allObjects.firstObject.URL;
NSUserActivity* userActivity = connectionOptions.userActivities.allObjects.firstObject;
if (url != nil) {
// track deeplink
[Airbridge trackDeeplinkWithUrl:url];
// handle deeplink
BOOL isHandled = [Airbridge handleDeeplinkWithUrl:url onSuccess:^(NSURL* url) {
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
[self handleAirbridgeDeeplink:url];
}];
if (isHandled) { return; }
// when app is opened with other deeplink
// use existing logic as it is
}
else if (userActivity != nil) {
// track deeplink
[Airbridge trackDeeplinkWithUserActivity:userActivity];
// handle deeplink
BOOL isHandled = [Airbridge handleDeeplinkWithUserActivity:userActivity onSuccess:^(NSURL* url) {
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
[self handleAirbridgeDeeplink:url];
}];
if (isHandled) { return; }
// when app is opened with other deeplink
// use existing logic as it is
}
}
3. 当后台中的 App 通过 URI Scheme 深度链接启用时,请在调用的函数中调用 Airbridge.handleDeeplink
函数。转换后的 URI Scheme 深度链接将用户发送到预设的目标页面。
import Airbridge
...
// when backgrounded app is opened with scheme deeplink
func scene(
_ scene: UIScene,
openURLContexts URLContexts: Set<UIOpenURLContext>
) {
guard let url = URLContexts.first?.url else { return }
// track deeplink
Airbridge.trackDeeplink(url: url)
// handle deeplink
var isHandled = Airbridge.handleDeeplink(url: url) { url in
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
handleAirbridgeDeeplink(url: url)
}
if isHandled { return }
// when app is opened with other deeplink
// use existing logic as it is
}
#import <Airbridge/Airbridge.h>
...
// when backgrounded app is opened with scheme deeplink
- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts {
NSURL* url = URLContexts.allObjects.firstObject.URL;
if (url == nil) { return; }
// track deeplink
[Airbridge trackDeeplinkWithUrl:url];
// handle deeplink
BOOL isHandled = [Airbridge handleDeeplinkWithUrl:url onSuccess:^(NSURL* url) {
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
[self handleAirbridgeDeeplink:url];
}];
if (isHandled) { return; }
// when app is opened with other deeplink
// use existing logic as it is
}
4. 当后台中的 App 通过 Universal Link 启用时,请在调用的函数中调用 Airbridge.handleDeeplink
函数。转换后的 URI Scheme 深度链接将用户发送到预设的目标页面。
import Airbridge
...
// when backgrounded app is opened with universal links
func scene(
_ scene: UIScene,
continue userActivity: NSUserActivity
) {
// track deeplink
Airbridge.trackDeeplink(userActivity: userActivity)
// handle deeplink
var isHandled = Airbridge.handleDeeplink(userActivity: userActivity) { url in
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
handleAirbridgeDeeplink(url: url)
}
if isHandled { return }
// when app is opened with other deeplink
// use existing logic as it is
}
// when backgrounded app is opened with universal links
- (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity {
// track deeplink
[Airbridge trackDeeplinkWithUserActivity:userActivity];
// handle deeplink
BOOL isHandled = [Airbridge handleDeeplinkWithUserActivity:userActivity onSuccess:^(NSURL* url) {
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
[self handleAirbridgeDeeplink:url];
}];
if (isHandled) { return; }
// when app is opened with other deeplink
// use existing logic as it is
}
请进行设置启用以下功能:
使用 Airbridge 深度链接启用 App
在 App 收集 Airbridge 深度链接事件
使用 Airbridge 深度链接实现用户跳转
当用户点击追踪链接时,App 应通过 Airbridge 深度链接启用。
1. 需要在 App 进行 Airbridge 深度链接的 URI Scheme 深度链接设置。请在 Xcode 中导航至 [YOUR_PROJECT]>[Info]>[URL Types]。
2. 请点击 “+”,并在 URL Schemes 中输入已在 Airbridge 面板中注册的 iOS URI Scheme。
注意
必须输入不包括
://
的 iOS URI Scheme。
3. 需要在 App 进行 Airbridge 深度链接的 Universal Link 设置。请在 Xcode 中导航至 [YOUR_PROJECT]>[Signing & Capabilities]。
4. 请点击 “+ Capability” 以添加 Associated Domains。
5. 请将 applinks:YOUR_APP_NAME.airbridge.io
和 applinks:YOUR_APP_NAME.abr.ge
添加到 Associated Domains。YOUR_APP_NAME
是 Airbridge App 名称。
注意
如果您正在使用或计划使用 Password AutoFill 功能,则必须添加 Webcredentials 域名。否则用户可能会看到通过 Password AutoFill 功能保存的密码域名显示为 airbridge.io 或 abr.ge。
更多信息请参阅 本指南。
注意
在 iOS,无法自动收集深度链接事件。必须使用
Airbridge.trackDeeplink
函数将深度链接事件传递给 Airbridge SDK。
为了收集深度链接事件,必须将深度链接事件传递给 Airbridge SDK。当 App 通过深度链接启用时,请在调用的 OS 回调顶部调用 Airbridge.trackDeeplink
函数。
import Airbridge
...
Airbridge.trackDeeplink(url: url)
Airbridge.trackDeeplink(userActivity: userActivity)
#import <Airbridge/Airbridge.h>
...
[Airbridge trackDeeplinkWithUrl:url];
[Airbridge trackDeeplinkWithUserActivity:userActivity];
当 App 通过 URI Scheme 深度链接或 Universal Link 启用时,请在调用的函数中调用 Airbridge.trackDeeplink
函数。Airbridge.trackDeeplink
函数将深度链接传递给 Airbridge SDK。
import SwiftUI
import Airbridge
@main
struct ActualApp: App {
var body: some Scene {
WindowGroup {
ContentView()
// when app is opened with scheme deeplink or universal links
.onOpenURL { url in
// track deeplink
Airbridge.trackDeeplink(url: url)
}
}
}
}
为确保将用户发送到目标页面,必须使用 Airbridge.handleDeeplink
函数将 Airbridge 深度链接转换为 URI Scheme 深度链接。
import Airbridge
...
// handle deeplink
var isHandled = Airbridge.handleDeeplink(url: url) { url in
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
}
if isHandled { return }
// when app is opened with other deeplink
// use existing logic as it is
...
// handle deeplink
var isHandled = Airbridge.handleDeeplink(userActivity: userActivity) { url in
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
}
if isHandled { return }
// when app is opened with other deeplink
// use existing logic as it is
#import <Airbridge/Airbridge.h>
...
// handle deeplink
BOOL isHandled = [Airbridge handleDeeplinkWithUrl:url onSuccess:^(NSURL* url) {
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
}];
if (isHandled) { return; }
// when app is opened with other deeplink
// use existing logic as it is
...
// handle deeplink
BOOL isHandled = [Airbridge handleDeeplinkWithUserActivity:userActivity onSuccess:^(NSURL* url) {
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
}];
if (isHandled) { return; }
// when app is opened with other deeplink
// use existing logic as it is
Airbridge.handleDeeplink
函数在输入 Airbridge 深度链接时,会返回 true
并通过回调提供 URI Scheme 深度链接。如果不是 Airbridge 深度链接,则返回 false
,且不提供回调。利用此功能,可以分开处理通过 Airbridge 启用的深度链接。
在通过深度链接启用的 App 调用的 OS 回调中,将 Airbridge.handleDeeplink
函数放置在 Airbridge.trackDeeplink
函数的正下方调用。如有必要,应将现有逻辑一并处理。
当 App 通过 URI Scheme 深度链接或 Universal Link 启用时,请在调用的函数中调用 Airbridge.handleDeeplink
函数。转换后的 URI Scheme 深度链接将用户发送到预设的目标页面。
import SwiftUI
import Airbridge
@main
struct ActualApp: App {
var body: some Scene {
WindowGroup {
ContentView()
// when app is opened with scheme deeplink or universal links
.onOpenURL { url in
// track deeplink
Airbridge.trackDeeplink(url: url)
// handle deeplink
var isHandled = Airbridge.handleDeeplink(url: url) { url in
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
}
if isHandled { return }
// when app is opened with other deeplink
// use existing logic as it is
}
}
}
}
请进行设置启用以下功能:
使用 Airbridge 深度链接启用 App
在 App 收集 Airbridge 深度链接事件
使用 Airbridge 深度链接实现用户跳转
当用户点击追踪链接时,App 应通过 Airbridge 深度链接启用。
1. 需要在 App 进行 Airbridge 深度链接的 URI Scheme 深度链接设置。请在 Xcode 中导航至 [YOUR_PROJECT]>[Info]>[URL Types]。
2. 请点击 “+”,并在 URL Schemes 中输入已在 Airbridge 面板中注册的 iOS URI Scheme。
注意
必须输入不包括
://
的 iOS URI Scheme。
3. 需要在 App 进行 Airbridge 深度链接的 Universal Link 设置。请在 Xcode 中导航至 [YOUR_PROJECT]>[Signing & Capabilities]。
4. 请点击 “+ Capability” 以添加 Associated Domains。
5. 请将 applinks:YOUR_APP_NAME.airbridge.io
和 applinks:YOUR_APP_NAME.abr.ge
添加到 Associated Domains。YOUR_APP_NAME
是 Airbridge App 名称。
注意
如果您正在使用或计划使用 Password AutoFill 功能,则必须添加 Webcredentials 域名。否则用户可能会看到通过 Password AutoFill 功能保存的密码域名显示为 airbridge.io 或 abr.ge。
更多信息请参阅 本指南。
注意
在 iOS,无法自动收集深度链接事件。必须使用
Airbridge.trackDeeplink
函数将深度链接事件传递给 Airbridge SDK。
为了收集深度链接事件,必须将深度链接事件传递给 Airbridge SDK。当 App 通过深度链接启用时,请在调用的 OS 回调顶部调用 Airbridge.trackDeeplink
函数。
import Airbridge
...
Airbridge.trackDeeplink(url: url)
Airbridge.trackDeeplink(userActivity: userActivity)
#import <Airbridge/Airbridge.h>
...
[Airbridge trackDeeplinkWithUrl:url];
[Airbridge trackDeeplinkWithUserActivity:userActivity];
具体设置方法因 Airbridge 深度链接类型而异。
1. 当 App 通过 URI Scheme 深度链接启用时,请在调用的函数中调用 Airbridge.trackDeeplink
函数。
import Airbridge
...
// when app is opened with scheme deeplink
func application(
_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey : Any] = [:]
) -> Bool {
// track deeplink
Airbridge.trackDeeplink(url: url)
return true
}
#import <Airbridge/Airbridge.h>
...
// when app is opened with scheme deeplink
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
// track deeplink
[Airbridge trackDeeplinkWithUrl:url];
return YES;
}
2. 当 App 通过 Universal Link 启用时,请在调用的函数中调用 Airbridge.trackDeeplink
函数。
// when app is opened with universal links
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
// track deeplink
Airbridge.trackDeeplink(userActivity: userActivity)
return true
}
#import <Airbridge/Airbridge.h>
...
// when app is opened with universal links
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
// track deeplink
[Airbridge trackDeeplinkWithUserActivity:userActivity];
return YES;
}
为确保将用户发送到目标页面,必须使用 Airbridge.handleDeeplink
函数将 Airbridge 深度链接转换为 URI Scheme 深度链接。
import Airbridge
...
// handle deeplink
var isHandled = Airbridge.handleDeeplink(url: url) { url in
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
}
if isHandled { return }
// when app is opened with other deeplink
// use existing logic as it is
...
// handle deeplink
var isHandled = Airbridge.handleDeeplink(userActivity: userActivity) { url in
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
}
if isHandled { return }
// when app is opened with other deeplink
// use existing logic as it is
#import <Airbridge/Airbridge.h>
...
// handle deeplink
BOOL isHandled = [Airbridge handleDeeplinkWithUrl:url onSuccess:^(NSURL* url) {
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
}];
if (isHandled) { return; }
// when app is opened with other deeplink
// use existing logic as it is
...
// handle deeplink
BOOL isHandled = [Airbridge handleDeeplinkWithUserActivity:userActivity onSuccess:^(NSURL* url) {
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
}];
if (isHandled) { return; }
// when app is opened with other deeplink
// use existing logic as it is
Airbridge.handleDeeplink
函数在输入 Airbridge 深度链接时,会返回 true
并通过回调提供 URI Scheme 深度链接。如果不是 Airbridge 深度链接,则返回 false
,且不提供回调。利用此功能,可以分开处理通过 Airbridge 启用的深度链接。
根据系统方式和 App 状态,在通过深度链接启用的 App 调用的 OS 回调中,将 Airbridge.handleDeeplink
函数放置在 Airbridge.trackDeeplink
函数的正下方调用。如有必要,应将现有逻辑一并处理。
1. 请在 AppDelegate 中实现用于处理通过 Airbridge 深度链接启用的 App 的函数。
import Foundation
...
// when app is opened with airbridge deeplink
func handleAirbridgeDeeplink(url: URL) {
// show proper content using url (YOUR_SCHEME://...)
}
import Foundation
...
// when app is opened with airbridge deeplink
- (void)handleAirbridgeDeeplink:(NSURL *)url {
// show proper content using url (YOUR_SCHEME://...)
}
2. 当 App 通过 URI Scheme 深度链接启用时,请在调用的函数中调用 Airbridge.handleDeeplink
函数。转换后的 URI Scheme 深度链接将用户发送到预设的目标页面。
import Airbridge
...
// when app is opened with scheme deeplink
func application(
_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey : Any] = [:]
) -> Bool {
// track deeplink
Airbridge.trackDeeplink(url: url)
// handle deeplink
var isHandled = Airbridge.handleDeeplink(url: url) { url in
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
handleAirbridgeDeeplink(url: url)
}
if isHandled { return }
// when app is opened with other deeplink
// use existing logic as it is
return isHandled
}
#import <Airbridge/Airbridge.h>
...
// when app is opened with scheme deeplink
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
// track deeplink
[Airbridge trackDeeplinkWithUrl:url];
// handle deeplink
BOOL isHandled = [Airbridge handleDeeplinkWithUrl:url onSuccess:^(NSURL* url) {
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
[self handleAirbridgeDeeplink:url];
}];
if (isHandled) { return; }
// when app is opened with other deeplink
// use existing logic as it is
return isHandled;
}
3. 当 App 通过 Universal Link 启用时,请在调用的函数中调用 Airbridge.handleDeeplink
函数。转换后的 URI Scheme 深度链接将用户发送到预设的目标页面。
// when app is opened with universal links
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
// track deeplink
Airbridge.trackDeeplink(userActivity: userActivity)
// handle deeplink
var isHandled = Airbridge.handleDeeplink(userActivity: userActivity) { url in
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
handleAirbridgeDeeplink(url: url)
}
if isHandled { return }
// when app is opened with other deeplink
// use existing logic as it is
return isHandled
}
#import <Airbridge/Airbridge.h>
...
// when app is opened with universal links
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
// track deeplink
[Airbridge trackDeeplinkWithUserActivity:userActivity];
// handle deeplink
BOOL isHandled = [Airbridge handleDeeplinkWithUserActivity:userActivity onSuccess:^(NSURL* url) {
// when app is opened with airbridge deeplink
// show proper content using url (YOUR_SCHEME://...)
[self handleAirbridgeDeeplink:url];
}];
if (isHandled) { return; }
// when app is opened with other deeplink
// use existing logic as it is
return isHandled;
}
当 App 未安装时,如果用户点击了设置了延迟深度链接的追踪链接,Airbridge 会保存深度链接信息。Airbridge SDK 会通过以下方法来获取保存的深度链接:
Airbridge SDK 在初始化以后,如果满足以下所有条件,会尝试获取深度链接。如果在获取深度链接的过程中 App 被关闭,Airbridge SDK 会将视为没有保存的深度链接。
已设置 Opt-in 时调用 Airbridge.startTracking
函数;或未设置 Opt-in。
用户在 ATT 弹窗中做出选择,或 ATT 弹窗中设置的事件收集延迟时间已到期。
Airbridge.handleDeferredDeeplink
函数在获取已保存的 Airbridge 深度链接后,会将 Airbridge 深度链接转换为 URI Scheme 深度链接,并将转换后的 URI Scheme 深度链接传递给 App。转换后的 URI Scheme 深度链接将用户发送至设置的目的页面。
import Airbridge
...
let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
.build()
Airbridge.initializeSDK(option: option)
...
let isHandled = Airbridge.handleDeferredDeeplink() { url in
if let url {
// show proper content using url (YOUR_SCHEME://...)
}
}
#import <Airbridge/Airbridge.h>
...
AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
token:@"YOUR_APP_SDK_TOKEN"];
AirbridgeOption* option = [optionBuilder build];
[Airbridge initializeSDKWithOption:option];
...
BOOL isHandled = [Airbridge handleDeferredDeeplinkOnSuccess:^(NSURL* url) {
if (url != nil) {
// show proper content using url (YOUR_SCHEME://...)
}
}];
Airbridge.handleDeferredDeeplink
函数在 App 安装后首次被调用时会返回 true
,并等待获取 Airbridge 深度链接,将其转换为 URI Scheme 深度链接后传递给 onSuccess。您可以使用该 URI Scheme 深度链接将用户发送至预设目标页面。
如果没有保存的 Airbridge 深度链接,则会向 onSuccess 传递 nil
。如果 SDK 尚未初始化,或 Airbridge.handleDeferredDeeplink
函数并非首次被调用,则会返回 false
。
传递的 URI Scheme 深度链接通常是 YOUR_SCHEME://...
格式的 URL。如果使用 Meta Deferred App Link 等服务,则可能会传递其他格式的 URL。
Airbridge SDK 会根据设置从您的服务中收集特定用户行为,并将其作为应用内事件发送。
Hybrid App 设置
在 Hybrid App 中,无需更改网站代码,即可通过设置使 iOS SDK 处理应用内网站上出现的与 Airbridge 相关的操作。
为了发送事件,需要调用 Airbridge.trackEvent
函数。Airbridge.trackEvent
函数构成要素及其必需性如下。
static func trackEvent(
category: String
)
static func trackEvent(
category: String,
semanticAttributes: [String : Any]
)
static func trackEvent(
category: String,
semanticAttributes: [String : Any],
customAttributes: [String : Any]
)
+ (void)trackEventWithCategory:(NSString*)category
+ (void)trackEventWithCategory:(NSString*)category
semanticAttributes:(NSDictionary*)semanticAttributes
+ (void)trackEventWithCategory:(NSString*)category
semanticAttributes:(NSDictionary*)semanticAttributes
customAttributes:(NSDictionary*)customAttributes
构成要素 | 是否必需 | 类型 | 说明 |
---|---|---|---|
category | 必需 | String | 事件名称 |
semanticAttributes | 可选 | [String: Any] | 事件标准属性 |
customAttributes | 可选 | [String: Any] | 事件自定义属性 |
各构成要素的定义和可用数据类型请参阅下文:
Airbridge SDK 提供的标准事件的 Category 可在 AirbridgeCategory 中查看。您也可以输入从标准事件列表中获取的 Category。
自定义事件可以通过输入在 事件结构(Event Taxonomy)中定义的事件名称发送。
请参阅以下的示例。
import Airbridge
...
// track standard event (provided by sdk)
Airbridge.trackEvent(category: AirbridgeCategory.ORDER_COMPLETED)
// track standard event (not provided by sdk)
Airbridge.trackEvent(category: "airbridge.ecommerce.order.canceled")
// track custom event
Airbridge.trackEvent(category: "eventViewed")
#import <Airbridge/Airbridge.h>
...
// track standard event (provided by sdk)
[Airbridge trackEventWithCategory:AirbridgeCategory.ORDER_COMPLETED];
// track standard event (not provided by sdk)
[Airbridge trackEventWithCategory:@"airbridge.ecommerce.order.canceled"];
// track custom event
[Airbridge trackEventWithCategory:@"eventViewed"];
注意
Airbridge SDK v4 的 Attribute 与旧版本不同。旧版本的 Attribute 不包含 Action、Label 和 Value。
您可以通过 Attribute 收集有关事件的详细信息。
Action、Label:收集可在 Airbridge 报告中用作分组的信息。
Value:收集用于分析收入的信息。通过 Value 收集的数据可用于计算。
Semantic Attribute:Airbridge 预定义的属性。
Custom Attribute:由 Airbridge 客户自定义的属性。
您可以通过 Airbridge.trackEvent
函数的 semanticAttributes
参数输入 Action、Label、Value 和 Semantic Attribute,并通过 customAttributes
参数输入 Custom Attribute。
Airbridge 提供的 Semantic Attribute 如下:
请参阅以下的示例。
import Airbridge
...
Airbridge.trackEvent(
category: AirbridgeCategory.ORDER_COMPLETED,
semanticAttributes: [
// action
AirbridgeAttribute.ACTION: "Tool",
// label
AirbridgeAttribute.LABEL: "Hammer",
// value
AirbridgeAttribute.VALUE: 10,
// semantic attribute (provided by sdk)
AirbridgeAttribute.CURRENCY: "USD",
AirbridgeAttribute.PRODUCTS: [
[
// semantic attribute value (provided by sdk)
AirbridgeAttribute.PRODUCT_ID: "12345",
// semantic attribute value (not provided by sdk)
"name": "PlasticHammer",
],
],
// semantic attribute (not provided by sdk)
"totalQuantity": 1,
],
customAttributes: [
// custom attribute
"promotion": "FirstPurchasePromotion",
]
)
#import <Airbridge/Airbridge.h>
...
[Airbridge trackEventWithCategory:@"event" semanticAttributes:@{
// action
AirbridgeAttribute.ACTION: @"Tool",
// label
AirbridgeAttribute.LABEL: @"Hammer",
// value
AirbridgeAttribute.VALUE: @(10),
// semantic attribute (provided by sdk)
AirbridgeAttribute.CURRENCY: @"USD",
AirbridgeAttribute.PRODUCTS: @[
@{
// semantic attribute value (provided by sdk)
AirbridgeAttribute.PRODUCT_ID: @"12345",
// semantic attribute value (not provided by sdk)
@"name": @"PlasticHammer",
},
],
// semantic attribute (not provided by sdk)
@"totalQuantity": @(1),
}, customAttributes:@{
// custom attribute
@"promotion": @"FirstPurchasePromotion",
}];
注意
Semantic Attribute 和 Custom Attribute 仅支持 JSON 数据类型。
JSON 类型:String、Number、Boolean、Object<String, JSON>、Array<JSON>
Semantic Attribute 和 Custom Attribute 不支持的类型:Struct、Class 等
SDK 提供的标准事件 Category 和 Semantic Attribute 如下:
键 | 类型 | 值 |
---|---|---|
SIGN_UP | String | airbridge.user.signup |
SIGN_IN | String | airbridge.user.signin |
SIGN_OUT | String | airbridge.user.signout |
HOME_VIEWED | String | airbridge.ecommerce.home.viewed |
PRODUCT_LIST_VIEWED | String | airbridge.ecommerce.productList.viewed |
SEARCH_RESULTS_VIEWED | String | airbridge.ecommerce.searchResults.viewed |
PRODUCT_VIEWED | String | airbridge.ecommerce.product.viewed |
ADD_PAYMENT_INFO | String | airbridge.addPaymentInfo |
ADD_TO_WISHLIST | String | airbridge.addToWishlist |
ADDED_TO_CART | String | airbridge.ecommerce.product.addedToCart |
INITIATE_CHECKOUT | String | airbridge.initiateCheckout |
ORDER_COMPLETED | String | airbridge.ecommerce.order.completed |
ORDER_CANCELED | String | airbridge.ecommerce.order.canceled |
START_TRIAL | String | airbridge.startTrial |
SUBSCRIBE | String | airbridge.subscribe |
UNSUBSCRIBE | String | airbridge.unsubscribe |
AD_IMPRESSION | String | airbridge.adImpression |
AD_CLICK | String | airbridge.adClick |
COMPLETE_TUTORIAL | String | airbridge.completeTutorial |
ACHIEVE_LEVEL | String | airbridge.achieveLevel |
UNLOCK_ACHIEVEMENT | String | airbridge.unlockAchievement |
RATE | String | airbridge.rate |
SHARE | String | airbridge.share |
SCHEDULE | String | airbridge.schedule |
SPEND_CREDITS | String | airbridge.spendCredits |
键 | 类型 | 值 |
---|---|---|
ACTION | String | action |
LABEL | String | label |
VALUE | String | value |
CURRENCY | String | currency |
ORIGINAL_CURRENCY | String | originalCurrency |
PRODUCTS | String | products |
PRODUCT_ID | String | productID |
PRODUCT_NAME | String | name |
PRODUCT_PRICE | String | price |
PRODUCT_QUANTITY | String | quantity |
PRODUCT_CURRENCY | String | currency |
PRODUCT_POSITION | String | position |
PRODUCT_CATEGORY_ID | String | categoryID |
PRODUCT_CATEGORY_NAME | String | categoryName |
PRODUCT_BRAND_ID | String | brandID |
PRODUCT_BRAND_NAME | String | brandName |
PERIOD | String | period |
IS_RENEWAL | String | isRenewal |
RENEWAL_COUNT | String | renewalCount |
PRODUCT_LIST_ID | String | productListID |
CART_ID | String | cartID |
TRANSACTION_ID | String | transactionID |
TRANSACTION_TYPE | String | transactionType |
TRANSACTION_PAIRED_EVENT_CATEGORY | String | transactionPairedEventCategory |
TRANSACTION_PAIRED_EVENT_TIMESTAMP | String | transactionPairedEventTimestamp |
TOTAL_QUANTITY | String | totalQuantity |
QUERY | String | query |
IN_APP_PURCHASED | String | inAppPurchased |
CONTRIBUTION_MARGIN | String | contributionMargin |
ORIGINAL_CONTRIBUTION_MARGIN | String | originalContributionMargin |
LIST_ID | String | listID |
RATE_ID | String | rateID |
RATE | String | rate |
MAX_RATE | String | maxRate |
ACHIEVEMENT_ID | String | achievementID |
SHARED_CHANNEL | String | sharedChannel |
DATE_TIME | String | datetime |
DESCRIPTION | String | description |
IS_REVENUE | String | isRevenue |
PLACE | String | place |
SCHEDULE_ID | String | scheduleID |
TYPE | String | type |
LEVEL | String | level |
SCORE | String | score |
AD_PARTNERS | String | adPartners |
IS_FIRST_PER_USER | String | isFirstPerUser |
各数据类型的示例代码如下:
import Airbridge
...
Airbridge.trackEvent(
category: "event",
semanticAttributes: [
AirbridgeAttribute.VALUE: 10,
],
customAttributes: [
"string": "string",
"number": 1000,
"boolean": true,
"object": ["key": "value"],
"array": ["value"],
]
)
#import <Airbridge/Airbridge.h>
...
[Airbridge trackEventWithCategory:@"event" semanticAttributes:@{
AirbridgeAttribute.VALUE: @(10),
} customAttributes:@{
@"string": "string",
@"number": @(1000),
@"boolean": @(YES),
@"object": @{@"key": @"value"},
@"array": @[@"value"],
@"key": @"value",
}];
提示
如果未配置其他设置,则将应用默认设置。请查看是否需要其他设置后再继续。
Airbridge SDK 按会话支持用户触发的事件。当满足以下任一条件时,会话将结束:
App 移至后台或关闭
App 处于前台时会话过期
如果会话结束后启用 App 或触发事件,则会开启新的会话。
默认会话超时设置为 300 秒。您可以使用 setSessionTimeout
函数修改此值,最长可达 604,800 秒(7 天)。
import Airbridge
...
let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
.setSessionTimeout(second: 300)
.build()
Airbridge.initializeSDK(option: option)
#import <Airbridge/Airbridge.h>
...
AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
token:@"YOUR_APP_SDK_TOKEN"];
[optionBuilder setSessionTimeoutWithSecond:300];
AirbridgeOption* option = [optionBuilder build];
[Airbridge initializeSDKWithOption:option];
注意
Airbridge SDK 会收集开启新会话的 Open 事件和 Foreground 事件。但在会话持续期间,这些事件不会被收集。如果希望在会话持续期间收集这些事件,则需要进行 额外设置。
Airbridge SDK 会将收集的事件保存下来,并逐一加载已保存的事件,直到所有事件发送成功。成功发送的事件将被移除。
发送失败的事件会根据失败的次数分别等待 1、2、4…… 秒后再次尝试发送。如果持续发送失败,则会按照设定的事件发送周期等待,并重复尝试重新加载并发送事件,直到发送成功为止。
默认事件发送周期为 0 秒,您可以使用 setEventTransmitInterval
函数修改此值,最长可达 86,400 秒(1 天)。
请参阅以下的示例。
import Airbridge
...
let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
.setEventTransmitInterval(second: 0)
.build()
Airbridge.initializeSDK(option: option)
#import <Airbridge/Airbridge.h>
...
AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
token:@"YOUR_APP_SDK_TOKEN"];
[optionBuilder setEventTransmitIntervalWithSecond:0];
AirbridgeOption* option = [optionBuilder build];
[Airbridge initializeSDKWithOption:option];
Airbridge SDK 仅在未超出最大事件数和最大事件大小限制的情况下保存事件。超出限制的事件将被丢弃。
可设置的最大事件数为 INT_MAX;可设置的最大事件大小为 1024 GiB(千兆字节)。默认的最大事件数也为 INT_MAX;默认的最大事件大小也为 1024 GiB(千兆字节)。您可以使用 setEventBufferCountLimit
函数和 setEventBufferSizeLimit
函数进行修改。
请参阅以下的示例。
import Airbridge
...
let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_TOKEN")
.setEventBufferCountLimit(Int.max)
.setEventBufferSizeLimit(gibibyte: 1024)
.build()
Airbridge.initializeSDK(option: option)
#import <Airbridge/Airbridge.h>
...
AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
token:@"YOUR_APP_TOKEN"];
[optionBuilder setEventBufferCountLimit:INT_MAX];
[optionBuilder setEventBufferSizeLimitWithGibibyte:1024];
AirbridgeOption* option = [optionBuilder build];
[Airbridge initializeSDKWithOption:option];
如果启用未发送事件删除选项,在 Airbridge SDK 初始化过程中未发送的所有已保存应用内事件将被删除。未发送事件删除选项默认为禁用。
您可以将 setClearEventBufferOnInitializeEnabled
函数设置为 true
,以启用未发送事件删除选项。
import Airbridge
...
let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_TOKEN")
.setClearEventBufferOnInitializeEnabled(true)
.build()
Airbridge.initializeSDK(option: option)
#import <Airbridge/Airbridge.h>
...
AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
token:@"YOUR_APP_TOKEN"];
[optionBuilder setClearEventBufferOnInitializeEnabled:YES];
AirbridgeOption* option = [optionBuilder build];
[Airbridge initializeSDKWithOption:option];
Airbridge SDK 支持在所有事件中包含设备标识符进行发送。
函数 |
说明 |
---|---|
| 输入其他设备标识符,最多可输入 10 个 - key:最多 128 个字符,必须符合正则表达式 - value:最多 128 个字符 |
| 从设备标识符中删除指定的设备标识符 |
| 删除所有设备标识符 |
请参阅以下的示例。
import Airbridge
...
Airbridge.setDeviceAlias(key: "string", value: "string")
Airbridge.removeDeviceAlias(key: "string")
Airbridge.clearDeviceAlias()
#import <Airbridge/Airbridge.h>
...
[Airbridge setDeviceAliasWithKey:@"string" value:@"string"];
[Airbridge removeDeviceAliasWithKey:@"string"];
[Airbridge clearDeviceAlias];
Airbridge 收集的主要应用内事件是标准事件和自定义事件。标准事件是 Airbridge 预定义的事件,请参阅以下的示例代码:
import Airbridge
...
Airbridge.setUserID("string")
Airbridge.setUserAlias(key: "string", value: "string")
Airbridge.setUserEmail("string")
Airbridge.setUserPhone("string")
Airbridge.setUserAttribute(key: "string", value: "string")
Airbridge.trackEvent(
category: AirbridgeCategory.SIGN_UP
)
#import <Airbridge/Airbridge.h>
...
[Airbridge setUserID:@"string"];
[Airbridge setUserAliasWithKey:@"string" value:@"string"];
[Airbridge setUserEmail:@"string"];
[Airbridge setUserPhone:@"string"];
[Airbridge setUserAttributeWithKey:@"string" value:@"string"];
[Airbridge trackEventWithCategory:AirbridgeCategory.SIGN_UP];
import Airbridge
...
Airbridge.setUserID("string")
Airbridge.setUserAlias(key: "string", value: "string")
Airbridge.setUserEmail("string")
Airbridge.setUserPhone("string")
Airbridge.setUserAttribute(key: "string", value: "string")
Airbridge.trackEvent(
category: AirbridgeCategory.SIGN_IN
)
#import <Airbridge/Airbridge.h>
...
[Airbridge setUserID:@"string"];
[Airbridge setUserAliasWithKey:@"string" value:@"string"];
[Airbridge setUserEmail:@"string"];
[Airbridge setUserPhone:@"string"];
[Airbridge setUserAttributeWithKey:@"string" value:@"string"];
[Airbridge trackEventWithCategory:AirbridgeCategory.SIGN_IN];
import Airbridge
...
Airbridge.trackEvent(
category: AirbridgeCategory.SIGN_OUT
)
Airbridge.clearUser()
#import <Airbridge/Airbridge.h>
...
[Airbridge trackEventWithCategory:AirbridgeCategory.SIGN_OUT];
[Airbridge clearUser];
import Airbridge
...
Airbridge.trackEvent(
category: AirbridgeCategory.HOME_VIEWED
)
#import <Airbridge/Airbridge.h>
...
[Airbridge trackEventWithCategory:AirbridgeCategory.HOME_VIEWED];
import Airbridge
...
Airbridge.trackEvent(
category: AirbridgeCategory.PRODUCT_LIST_VIEWED,
semanticAttributes: [
AirbridgeAttribute.LIST_ID: "84e6e236-38c4-48db-9b49-16e4cc064386",
AirbridgeAttribute.PRODUCTS: [
[
AirbridgeAttribute.PRODUCT_ID: "0117b32a-5a6c-4d4c-b64c-7858e07dba78",
AirbridgeAttribute.PRODUCT_NAME: "PlasticHammer",
AirbridgeAttribute.PRODUCT_PRICE: 10,
AirbridgeAttribute.PRODUCT_QUANTITY: 1,
AirbridgeAttribute.PRODUCT_CURRENCY: "USD",
],
[
AirbridgeAttribute.PRODUCT_ID: "d6ab2fbe-decc-4362-b719-d257a131e91e",
AirbridgeAttribute.PRODUCT_NAME: "PlasticFork",
AirbridgeAttribute.PRODUCT_PRICE: 1,
AirbridgeAttribute.PRODUCT_QUANTITY: 1,
AirbridgeAttribute.PRODUCT_CURRENCY: "USD",
],
],
]
)
#import <Airbridge/Airbridge.h>
...
[Airbridge trackEventWithCategory:AirbridgeCategory.PRODUCT_LIST_VIEWED semanticAttributes:@{
AirbridgeAttribute.LIST_ID: @"84e6e236-38c4-48db-9b49-16e4cc064386",
AirbridgeAttribute.PRODUCTS: @[
@{
AirbridgeAttribute.PRODUCT_ID: @"0117b32a-5a6c-4d4c-b64c-7858e07dba78",
AirbridgeAttribute.PRODUCT_NAME: @"PlasticHammer",
AirbridgeAttribute.PRODUCT_PRICE: @(10),
AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
},
@{
AirbridgeAttribute.PRODUCT_ID: @"d6ab2fbe-decc-4362-b719-d257a131e91e",
AirbridgeAttribute.PRODUCT_NAME: @"PlasticFork",
AirbridgeAttribute.PRODUCT_PRICE: @(1),
AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
},
],
}];
import Airbridge
...
Airbridge.trackEvent(
category: AirbridgeCategory.SEARCH_RESULTS_VIEWED,
semanticAttributes: [
AirbridgeAttribute.QUERY: "Plastic",
AirbridgeAttribute.PRODUCTS: [
[
AirbridgeAttribute.PRODUCT_ID: "0117b32a-5a6c-4d4c-b64c-7858e07dba78",
AirbridgeAttribute.PRODUCT_NAME: "PlasticHammer",
AirbridgeAttribute.PRODUCT_PRICE: 10,
AirbridgeAttribute.PRODUCT_QUANTITY: 1,
AirbridgeAttribute.PRODUCT_CURRENCY: "USD",
],
[
AirbridgeAttribute.PRODUCT_ID: "d6ab2fbe-decc-4362-b719-d257a131e91e",
AirbridgeAttribute.PRODUCT_NAME: "PlasticFork",
AirbridgeAttribute.PRODUCT_PRICE: 1,
AirbridgeAttribute.PRODUCT_QUANTITY: 1,
AirbridgeAttribute.PRODUCT_CURRENCY: "USD",
],
],
]
)
#import <Airbridge/Airbridge.h>
...
[Airbridge trackEventWithCategory:AirbridgeCategory.SEARCH_RESULTS_VIEWED semanticAttributes:@{
AirbridgeAttribute.QUERY: @"Plastic",
AirbridgeAttribute.PRODUCTS: @[
@{
AirbridgeAttribute.PRODUCT_ID: @"0117b32a-5a6c-4d4c-b64c-7858e07dba78",
AirbridgeAttribute.PRODUCT_NAME: @"PlasticHammer",
AirbridgeAttribute.PRODUCT_PRICE: @(10),
AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
},
@{
AirbridgeAttribute.PRODUCT_ID: @"d6ab2fbe-decc-4362-b719-d257a131e91e",
AirbridgeAttribute.PRODUCT_NAME: @"PlasticFork",
AirbridgeAttribute.PRODUCT_PRICE: @(1),
AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
},
],
}];
import Airbridge
...
Airbridge.trackEvent(
category: AirbridgeCategory.PRODUCT_VIEWED,
semanticAttributes: [
AirbridgeAttribute.PRODUCTS: [
[
AirbridgeAttribute.PRODUCT_ID: "0117b32a-5a6c-4d4c-b64c-7858e07dba78",
AirbridgeAttribute.PRODUCT_NAME: "PlasticHammer",
AirbridgeAttribute.PRODUCT_PRICE: 10,
AirbridgeAttribute.PRODUCT_QUANTITY: 1,
AirbridgeAttribute.PRODUCT_CURRENCY: "USD",
],
],
]
)
#import <Airbridge/Airbridge.h>
...
[Airbridge trackEventWithCategory:AirbridgeCategory.PRODUCT_VIEWED semanticAttributes:@{
AirbridgeAttribute.PRODUCTS: @[
@{
AirbridgeAttribute.PRODUCT_ID: @"0117b32a-5a6c-4d4c-b64c-7858e07dba78",
AirbridgeAttribute.PRODUCT_NAME: @"PlasticHammer",
AirbridgeAttribute.PRODUCT_PRICE: @(10),
AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
},
],
}];
import Airbridge
...
Airbridge.trackEvent(
category: AirbridgeCategory.ADD_PAYMENT_INFO,
semanticAttributes: [
AirbridgeAttribute.TYPE: "CreditCard",
]
)
#import <Airbridge/Airbridge.h>
...
[Airbridge trackEventWithCategory:AirbridgeCategory.ADD_PAYMENT_INFO semanticAttributes:@{
AirbridgeAttribute.TYPE: @"CreditCard",
}];
import Airbridge
...
Airbridge.trackEvent(
category: AirbridgeCategory.ADD_TO_WISHLIST,
semanticAttributes: [
AirbridgeAttribute.LIST_ID: "189a2f8b-83ee-4074-8158-726be54e57d4",
AirbridgeAttribute.CURRENCY: "USD",
AirbridgeAttribute.PRODUCTS: [
[
AirbridgeAttribute.PRODUCT_ID: "0117b32a-5a6c-4d4c-b64c-7858e07dba78",
AirbridgeAttribute.PRODUCT_NAME: "PlasticHammer",
AirbridgeAttribute.PRODUCT_PRICE: 10,
AirbridgeAttribute.PRODUCT_QUANTITY: 1,
AirbridgeAttribute.PRODUCT_CURRENCY: "USD",
],
],
]
)
#import <Airbridge/Airbridge.h>
...
[Airbridge trackEventWithCategory:AirbridgeCategory.ADD_TO_WISHLIST semanticAttributes:@{
AirbridgeAttribute.LIST_ID: @"189a2f8b-83ee-4074-8158-726be54e57d4",
AirbridgeAttribute.CURRENCY: @"USD",
AirbridgeAttribute.PRODUCTS: @[
@{
AirbridgeAttribute.PRODUCT_ID: @"0117b32a-5a6c-4d4c-b64c-7858e07dba78",
AirbridgeAttribute.PRODUCT_NAME: @"PlasticHammer",
AirbridgeAttribute.PRODUCT_PRICE: @(10),
AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
},
],
}];
import Airbridge
...
Airbridge.trackEvent(
category: AirbridgeCategory.ADDED_TO_CART,
semanticAttributes: [
AirbridgeAttribute.CART_ID: "421eaeb7-6e80-4694-933e-f2e1a55e9cbd",
AirbridgeAttribute.CURRENCY: "USD",
AirbridgeAttribute.PRODUCTS: [
[
AirbridgeAttribute.PRODUCT_ID: "0117b32a-5a6c-4d4c-b64c-7858e07dba78",
AirbridgeAttribute.PRODUCT_NAME: "PlasticHammer",
AirbridgeAttribute.PRODUCT_PRICE: 10,
AirbridgeAttribute.PRODUCT_QUANTITY: 1,
AirbridgeAttribute.PRODUCT_CURRENCY: "USD",
],
],
]
)
#import <Airbridge/Airbridge.h>
...
[Airbridge trackEventWithCategory:AirbridgeCategory.ADDED_TO_CART semanticAttributes:@{
AirbridgeAttribute.CART_ID: @"421eaeb7-6e80-4694-933e-f2e1a55e9cbd",
AirbridgeAttribute.CURRENCY: @"USD",
AirbridgeAttribute.PRODUCTS: @[
@{
AirbridgeAttribute.PRODUCT_ID: @"0117b32a-5a6c-4d4c-b64c-7858e07dba78",
AirbridgeAttribute.PRODUCT_NAME: @"PlasticHammer",
AirbridgeAttribute.PRODUCT_PRICE: @(10),
AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
},
],
}];
import Airbridge
...
Airbridge.trackEvent(
category: AirbridgeCategory.INITIATE_CHECKOUT,
semanticAttributes: [
AirbridgeAttribute.TRANSACTION_ID: "0a7ee1ec-33da-4ffb-b775-89e80e75978a",
AirbridgeAttribute.CURRENCY: "USD",
AirbridgeAttribute.PRODUCTS: [
[
AirbridgeAttribute.PRODUCT_ID: "0117b32a-5a6c-4d4c-b64c-7858e07dba78",
AirbridgeAttribute.PRODUCT_NAME: "PlasticHammer",
AirbridgeAttribute.PRODUCT_PRICE: 10,
AirbridgeAttribute.PRODUCT_QUANTITY: 1,
AirbridgeAttribute.PRODUCT_CURRENCY: "USD",
],
[
AirbridgeAttribute.PRODUCT_ID: "d6ab2fbe-decc-4362-b719-d257a131e91e",
AirbridgeAttribute.PRODUCT_NAME: "PlasticFork",
AirbridgeAttribute.PRODUCT_PRICE: 1,
AirbridgeAttribute.PRODUCT_QUANTITY: 1,
AirbridgeAttribute.PRODUCT_CURRENCY: "USD",
],
],
]
)
#import <Airbridge/Airbridge.h>
...
[Airbridge trackEventWithCategory:AirbridgeCategory.INITIATE_CHECKOUT semanticAttributes:@{
AirbridgeAttribute.TRANSACTION_ID: @"0a7ee1ec-33da-4ffb-b775-89e80e75978a",
AirbridgeAttribute.CURRENCY: @"USD",
AirbridgeAttribute.PRODUCTS: @[
@{
AirbridgeAttribute.PRODUCT_ID: @"0117b32a-5a6c-4d4c-b64c-7858e07dba78",
AirbridgeAttribute.PRODUCT_NAME: @"PlasticHammer",
AirbridgeAttribute.PRODUCT_PRICE: @(10),
AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
},
@{
AirbridgeAttribute.PRODUCT_ID: @"d6ab2fbe-decc-4362-b719-d257a131e91e",
AirbridgeAttribute.PRODUCT_NAME: @"PlasticFork",
AirbridgeAttribute.PRODUCT_PRICE: @(1),
AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
},
],
}];
import Airbridge
...
Airbridge.trackEvent(
category: AirbridgeCategory.ORDER_COMPLETED,
semanticAttributes: [
AirbridgeAttribute.VALUE: 11,
AirbridgeAttribute.TRANSACTION_ID: "8065ef16-162b-4a82-b683-e51aefdda7d5",
AirbridgeAttribute.CURRENCY: "USD",
AirbridgeAttribute.IN_APP_PURCHASED: true,
AirbridgeAttribute.PRODUCTS: [
[
AirbridgeAttribute.PRODUCT_ID: "0117b32a-5a6c-4d4c-b64c-7858e07dba78",
AirbridgeAttribute.PRODUCT_NAME: "PlasticHammer",
AirbridgeAttribute.PRODUCT_PRICE: 10,
AirbridgeAttribute.PRODUCT_QUANTITY: 1,
AirbridgeAttribute.PRODUCT_CURRENCY: "USD",
],
[
AirbridgeAttribute.PRODUCT_ID: "d6ab2fbe-decc-4362-b719-d257a131e91e",
AirbridgeAttribute.PRODUCT_NAME: "PlasticFork",
AirbridgeAttribute.PRODUCT_PRICE: 1,
AirbridgeAttribute.PRODUCT_QUANTITY: 1,
AirbridgeAttribute.PRODUCT_CURRENCY: "USD",
],
],
]
)
#import <Airbridge/Airbridge.h>
...
[Airbridge trackEventWithCategory:AirbridgeCategory.ORDER_COMPLETED semanticAttributes:@{
AirbridgeAttribute.VALUE: @(11),
AirbridgeAttribute.TRANSACTION_ID: @"8065ef16-162b-4a82-b683-e51aefdda7d5",
AirbridgeAttribute.CURRENCY: @"USD",
AirbridgeAttribute.IN_APP_PURCHASED: @(YES),
AirbridgeAttribute.PRODUCTS: @[
@{
AirbridgeAttribute.PRODUCT_ID: @"0117b32a-5a6c-4d4c-b64c-7858e07dba78",
AirbridgeAttribute.PRODUCT_NAME: @"PlasticHammer",
AirbridgeAttribute.PRODUCT_PRICE: @(10),
AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
},
@{
AirbridgeAttribute.PRODUCT_ID: @"d6ab2fbe-decc-4362-b719-d257a131e91e",
AirbridgeAttribute.PRODUCT_NAME: @"PlasticFork",
AirbridgeAttribute.PRODUCT_PRICE: @(1),
AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
},
],
}];
import Airbridge
...
Airbridge.trackEvent(
category: AirbridgeCategory.ORDER_CANCELED,
semanticAttributes: [
AirbridgeAttribute.VALUE: 11,
AirbridgeAttribute.TRANSACTION_ID: "8065ef16-162b-4a82-b683-e51aefdda7d5",
AirbridgeAttribute.CURRENCY: "USD",
AirbridgeAttribute.IN_APP_PURCHASED: true,
AirbridgeAttribute.PRODUCTS: [
[
AirbridgeAttribute.PRODUCT_ID: "0117b32a-5a6c-4d4c-b64c-7858e07dba78",
AirbridgeAttribute.PRODUCT_NAME: "PlasticHammer",
AirbridgeAttribute.PRODUCT_PRICE: 10,
AirbridgeAttribute.PRODUCT_QUANTITY: 1,
AirbridgeAttribute.PRODUCT_CURRENCY: "USD",
],
[
AirbridgeAttribute.PRODUCT_ID: "d6ab2fbe-decc-4362-b719-d257a131e91e",
AirbridgeAttribute.PRODUCT_NAME: "PlasticFork",
AirbridgeAttribute.PRODUCT_PRICE: 1,
AirbridgeAttribute.PRODUCT_QUANTITY: 1,
AirbridgeAttribute.PRODUCT_CURRENCY: "USD",
],
],
]
)
#import <Airbridge/Airbridge.h>
...
[Airbridge trackEventWithCategory:AirbridgeCategory.ORDER_CANCELED semanticAttributes:@{
AirbridgeAttribute.VALUE: @(11),
AirbridgeAttribute.TRANSACTION_ID: @"8065ef16-162b-4a82-b683-e51aefdda7d5",
AirbridgeAttribute.CURRENCY: @"USD",
AirbridgeAttribute.IN_APP_PURCHASED: @(YES),
AirbridgeAttribute.PRODUCTS: @[
@{
AirbridgeAttribute.PRODUCT_ID: @"0117b32a-5a6c-4d4c-b64c-7858e07dba78",
AirbridgeAttribute.PRODUCT_NAME: @"PlasticHammer",
AirbridgeAttribute.PRODUCT_PRICE: @(10),
AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
},
@{
AirbridgeAttribute.PRODUCT_ID: @"d6ab2fbe-decc-4362-b719-d257a131e91e",
AirbridgeAttribute.PRODUCT_NAME: @"PlasticFork",
AirbridgeAttribute.PRODUCT_PRICE: @(1),
AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
},
],
}];
import Airbridge
...
Airbridge.trackEvent(
category: AirbridgeCategory.START_TRIAL,
semanticAttributes: [
AirbridgeAttribute.TRANSACTION_ID: "ef1e5271-0370-407c-b1e9-669a8df1dc2c",
AirbridgeAttribute.CURRENCY: "USD",
AirbridgeAttribute.PERIOD: "P1M",
AirbridgeAttribute.PRODUCTS: [
[
AirbridgeAttribute.PRODUCT_ID: "306a57cb-f653-4220-a208-8405d8e4d506",
AirbridgeAttribute.PRODUCT_NAME: "MusicStreamingMemebership",
AirbridgeAttribute.PRODUCT_PRICE: 15,
AirbridgeAttribute.PRODUCT_CURRENCY: "USD",
],
],
]
)
#import <Airbridge/Airbridge.h>
...
[Airbridge trackEventWithCategory:AirbridgeCategory.START_TRIAL semanticAttributes:@{
AirbridgeAttribute.TRANSACTION_ID: @"ef1e5271-0370-407c-b1e9-669a8df1dc2c",
AirbridgeAttribute.CURRENCY: @"USD",
AirbridgeAttribute.PERIOD: @"P1M",
AirbridgeAttribute.PRODUCTS: @[
@{
AirbridgeAttribute.PRODUCT_ID: @"306a57cb-f653-4220-a208-8405d8e4d506",
AirbridgeAttribute.PRODUCT_NAME: @"MusicStreamingMemebership",
AirbridgeAttribute.PRODUCT_PRICE: @(15),
AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
},
],
}];
import Airbridge
...
Airbridge.trackEvent(
category: AirbridgeCategory.SUBSCRIBE,
semanticAttributes: [
AirbridgeAttribute.VALUE: 15,
AirbridgeAttribute.CURRENCY: "USD",
AirbridgeAttribute.TRANSACTION_ID: "cbe718c7-e44e-4707-b5cd-4a6a29f29649",
AirbridgeAttribute.PERIOD: "P1M",
AirbridgeAttribute.IS_RENEWAL: true,
AirbridgeAttribute.PRODUCTS: [
[
AirbridgeAttribute.PRODUCT_ID: "306a57cb-f653-4220-a208-8405d8e4d506",
AirbridgeAttribute.PRODUCT_NAME: "MusicStreamingMemebership",
AirbridgeAttribute.PRODUCT_PRICE: 15,
AirbridgeAttribute.PRODUCT_CURRENCY: "USD",
],
],
]
)
#import <Airbridge/Airbridge.h>
...
[Airbridge trackEventWithCategory:AirbridgeCategory.SUBSCRIBE semanticAttributes:@{
AirbridgeAttribute.VALUE: @(15),
AirbridgeAttribute.CURRENCY: @"USD",
AirbridgeAttribute.TRANSACTION_ID: @"cbe718c7-e44e-4707-b5cd-4a6a29f29649",
AirbridgeAttribute.PERIOD: @"P1M",
AirbridgeAttribute.IS_RENEWAL: @(YES),
AirbridgeAttribute.PRODUCTS: @[
@{
AirbridgeAttribute.PRODUCT_ID: @"306a57cb-f653-4220-a208-8405d8e4d506",
AirbridgeAttribute.PRODUCT_NAME: @"MusicStreamingMemebership",
AirbridgeAttribute.PRODUCT_PRICE: @(15),
AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
},
],
}];