iOS SDK

GitHub Tag

SDK 安装

注意

iOS SDK 1.35.1 以下版本存在已知问题。建议使用 1.35.1 及以上版本。

包安装

CocoaPods

1. 请使用以下命令创建 Podfile 文件:

12
cd path/to/project
touch Podfile

2. 请填充 Podfile 文件内容,如下所示:

Podfile
123
target '[Project Name]' do
    pod 'AirBridge', '1.40.0'
end

Airbridge iOS SDK 1.18.0 及以上版本需要 CocoaPods 1.11.0 及以上版本。

3. 请打开终端,输入以下命令:

12
cd path/to/project
pod install --repo-update

如果没有 pod 命令,请使用以下命令首先安装 CocoaPods:

  • sudo gem install cocoapods

SPM(Swift Package Manager)

您可以通过 SPM 安装 iOS SDK。从 SDK 1.23.0 版本开始支持 SPM。

1. 请在 Xcode 导航至 [File]>[Add packages...]。

2. 在弹出的 Apple Swift Package 窗口中,请搜索 Airbridge 包的地址(https://github.com/ab180/airbridge-ios-sdk-deploy),选择所需版本,然后点击 Add package 按钮。

3. 请选择所需 Target 后添加包。

4. 如果 SDK 安装正确,AirBridge 将显示在 Package Dependencies 中。

直接安装

1. AirBridge.framework 添加

  1. 请下载 AirBridge.framework

  2. 请导航至 [Xcode]>[Project file]>[General]>[Frameworks, Libraries, and Embedded Content]>[+]。

  3. 请点击 [Add Other...]>[Add Files...] 添加在步骤1.下载的 AirBridge.xcframework 文件夹。

  4. 请将 AirBridge.xcframework 设置为 Embed & Sign。

2. Dependency framework 添加

  1. 请导航至 [Xcode]>[Project file]>[General]>[Frameworks, Libraries, and Embedded Content]>[+]。

  2. 请添加下方表格中的 5 个 Framework。

  3. 请将已添加的 5 个 Framework 设置为 Do not Embed。

  4. 请导航至 [Xcode]>[Project file]>[Build Phase]>[Link Binary with Libraries]。

  5. 请将 5 个 Framework 的 Status 设置为 Optional。

Framework

说明

AdSupport.framework

用于收集 IDFA。

CoreTelephony.framework

用于收集移动通讯运营商信息。

StoreKit.framework

用于收集 SKAN 信息。

AppTrackingTransparency.framework

用于收集 ATT 同意状态信息。

AdServices.framework

由于收集 Apple Search Ads 归因信息(iOS 14.3 及以上)。

Project 设置

请将以下代码添加至 AppDelegate 的 application(_:didFinishLaunchingWithOptions:) 顶部以初始化 SDK。

123456
#import <AirBridge/AirBridge.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
    [AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
    ...
}

如果使用 AppDelegate 不存在的 SwiftUI 环境,请在 @main 存在的 App 类初始化 SDK。

1234567891011121314151617
// YourprojectApp.swift

import SwiftUI
import AirBridge

@main
struct OnlyUIApp: App {
    init() {
        AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName: "YOUR_APP_NAME")
    }
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

YOUR_APP_NAMEYOUR_APP_SDK_TOKEN 可在 Airbridge 面板的 [设置] >[Token] 获取。

IDFA 条款接受

为了使用 iOS SDK,需要在应用商店发布 App 时接受《IDFA 条款》。

  1. 请在 “Does this app use the Advertising Identifier (IDFA)?” 项目勾选 “Yes”。

  2. 请勾选 “Attribute this app installation to a previously served advertisement.” 项目。

  3. 请勾选 “Attribute an action taken within this app to a previously served advertisement.” 项目。

  4. 请勾选 “Limit Ad Tracking setting in iOS" 同意项目。

检查 SDK 安装

请查看安装并启用 App 时,安装(Install)事件是否收集到。

在 Airbridge 面板检查

从 SDK 发生的事件可在 Airbridge 面板的 [原始数据]>[App 实时记录] 查看。

1. 请导航至 Airbridge 面板的 [原始数据]>[App 实时记录]。

2. 请在搜索栏中输入已安装并启用 App 的设备的 IDFA。实时记录最多可能会有 5 分钟的延迟。

通过 Log 检查

请在 SDK 初始化代码顶部输入以下代码以输出 SDK Log:

12
[AirBridge setLogLevel:AB_LOG_ALL];
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];

深度链接(Deep Link)设置

Airbridge 面板设置

请在 Airbridge 面板的 [追踪链接]>[深度链接] 注册 2 项信息:

  • iOS URI Scheme

  • iOS App ID

iOS URI Scheme

请在 iOS URI Scheme 输入栏输入您的 iOS URI Scheme,包括 ://

注意

请为已发布或即将发布的 App 和开发用的 App 注册不同的 URI Scheme。

如果已发布或即将发布的 App 与开发用的 App 具有相同的 URI Scheme,深度链接可能会打开意外的 App。

iOS App ID

1. 请导航至 [https://developer.apple.com/account/resources]>[Identifiers]。

2. 请点击要追踪的 App 的 Identifier 获取 App ID Prefix 和 Bundle ID。

3. 请在 Airbridge 面板的 iOS App ID 输入栏输入 App ID Prefix+ .+ Bundle ID

  • 示例:9JA89QQLNQ.com.apple.wwdc

Project 设置

Scheme

1. 请导航至 [Xcode]>[Project file]>[Info]>[URL Types]。

2. 请在 URL Schemes 输入栏输入在 Airbridge 面板注册的 iOS URI Scheme。

注意

输入 URI Scheme 时请省略 ://

1. 请导航至 [Xcode]>[Project file]>[Signing & Capabilities]。

2. 请点击 [+ Capability] 添加 Associated Domains。

3. 请将 applinks:YOUR_APP_NAME.airbridge.io 添加至 Associated Domains。

4. 请将 applinks:YOUR_APP_NAME.abr.ge 添加至 Associated Domains。

YOUR_APP_NAME 可在 Airbridge 面板的 [设置] >[Token] 获取。

如果使用 Autofill 功能,请参阅 [Troubleshooting]>[Webcredentials]

向 SDK 传递深度链接信息

使用 AppDelegate 时

支持 iOS 12 及以下版本的 App 通常在 AppDelegate 的 application(_:open:options:) 方法中传递事件。

1. 请打开 ios/[Project 名称]/AppDelegate 文件。

2. 请在以下函数顶部调用 handleURLSchemeDeeplink 函数,以便当 App 通过 Scheme 打开时,将深度链接信息传递给 SDK:

12345678
- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
            options:(NSDictionary<UIApplicationOpenURLOptionsKey, id>*)options
{
    [AirBridge.deeplink handleURLSchemeDeeplink:url];

    return YES;
}

3. 请在以下函数顶部调用 handleUserActivity 函数,以便当 App 通过 Universal Link 打开时,将深度链接信息传递给 SDK:

12345678
-  (BOOL)application:(UIApplication*)application
continueUserActivity:(NSUserActivity*)userActivity
  restorationHandler:(void (^)(NSArray* _Nullable))restorationHandler
{
    [AirBridge.deeplink handleUserActivity:userActivity];

    return YES;
}

Attention

使用 SceneDelegate 的 Project 将通过 SceneDelegate 传递 URL,而非通过 AppDelegate。有关通过 SceneDelegate 收取 URL 的方法,请参阅下方的 "使用 SceneDelegate 时" 部分。

使用 SceneDelegate 时

支持 iOS 13 及以上版本的 App 中,如果使用 SceneDelegate,将通过以下方法传递深度链接:

  • App 在 Not Running 状态下加载时:scene(_:willConnectTo:options:)

  • 在所有其他情况下(例:Background 状态)

    • Universal Link:scene(_:continue:)

    • Scheme Link:scene(_:openURLContexts:)

123456789101112131415161718192021222324252627282930313233343536
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)
        // ...
    }
}

AppDelegate 和 SceneDelegate 都不使用时(SwiftUI)

如果使用不具有 SceneDelegate 的 SwiftUI,深度链接将通过 onOpenUrl 传递。请在 @main 存在的 App 类添加此方法。

123456789101112131415161718192021222324252627
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)
                    }
                }
        }
    }
}

注意

如果使用具有 SceneDelegate 的 SwiftUI Project,无法使用 onOpenUrl。请参阅上方的 “使用 SceneDelegate 时” 部分。

使用 AppDelegate 时

1. 请打开 ios/[Project 名称]/AppDelegate 文件。

2. 请在 AppDelegate 的 application(_:didFinishLaunchingWithOptions:) 使用 setDeeplinkCallback 函数设置回调,以便在 App 通过深度链接打开时调用。

123456789
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
    [AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];

    [AirBridge.deeplink setDeeplinkCallback:^(NSString* deeplink) {
        // 딥링크로 앱이 열리는 경우 작동할 코드
        // Airbridge 를 통한 Deeplink = YOUR_SCHEME://...
        NSLog(@"DeeplinkCallback : %@", deeplink);
    }];
}

不使用 AppDelegate 时(SwiftUI)

请在 @main 存在的 App 类添加相应的方法:

12345678910111213141516171819
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()
        }
    }
}
  • 使用 Airbridge iOS SDK 1.10.0 ~ 1.10.9 版本时,Airbridge 深度链接将以 https://YOUR_APP_NAME.airbridge.io/... 格式传递。

  • 使用 Airbridge iOS SDK ~ 1.9.10 版本时,Airbridge 深度链接将以 https://YOUR_APP_NAME.airbridge.io/...YOUR_SCHEME://... 格式传递。

延迟深度链接(Deferred Deep Link)设置

如果设置深度链接回调,延迟深度链接信息也将通过同样的深度链接回调传递。有关延迟深度链接回调设置,请参阅 深度链接回调(Deep Link Callback)设置

延迟深度链接回调仅在 App 安装后提供 1 次。

检查深度链接设置

1. 请点击在 Airbridge 面板注册的 YOUR_SCHEME://... 格式的 iOS URI Scheme。

2. 请检查是否打开了正确的 App 页面、并且在 Airbridge 面板的 [原始数据]>[App 实时记录] 存在深度链接打开(Deeplink Open)事件。

用户设置

用户标识符设置

您可在 SDK 中设置用户标识符,使以后收集的所有事件包含用户标识符。

12345678
[AirBridge.state setUserID:@"testID"];
[AirBridge.state setUserEmail:@"testID@ab180.co"];
[AirBridge.state setUserPhone:@"000-0000-0000"];

// 입력된 dictionary 로 user alias 가 교체됩니다.
[AirBridge.state setUserAlias:@{@"key": @"value"}];
// 기존의 user alias 에 해당 key, value 가 추가됩니다.
[AirBridge.state addUserAliasWithKey:@"key" value:@"value"];

名称

说明

限制

id

用户 ID

-

email

用户邮箱

将自动进行 SHA256 哈希处理(可选停用)

phone

用户电话号码

将自动进行 SHA256 哈希处理(可选停用)

alias

可以代表用户的其他 ID

- 最多可设置 10 个。
- key 是 NSString 类型,最多为 128 个字符。
- key 必须符合正则表达式 ^ {
"h-0": "名称"*$
- value 是 NSString 类型,最多为 128 个字符。

用户属性设置

您可以为提高 MTA(Multi-touch attribution, 多触点归因)分析的准确性、内部数据分析以及与第三方解决方案的集成等目的设置附加用户属性。

1234
// 입력된 dictionary 로 user attributes 가 교체됩니다.
[AirBridge.state setUserAttributes:@{@"key": @"value"}];
// 기존의 user attributes 에 해당 key, value 가 추가됩니다.
[AirBridge.state addUserAttributesWithKey:@"key" value:@"value"];

名称

说明

限制

attribute

用户属性

- 最多可设置 100 个。
- key 是 NSString 类型,最多为 128 个字符。
- key 必须符合正则表达式 ^ {
"h-0": "名称"*$
- value 类型可以为 NSString 或 NSNumber。
- value 类型如果是 NSString,则最多为 1024 个字符。

检查用户设置

1. 请完成用户设置。

2. 请通过 SDK 发送事件。

3. 请在 Airbridge 面板的 [原始数据]>[App 实时记录] 搜索并点击在步骤 2. 发送的事件,查看是否在 JSON 的 user 部分包含已设置的用户信息。

设备设置

设备标识符设置

您可在 SDK 中设置设备标识符,使以后收集的所有事件包含设备标识符。设置后,无论 App 是否关闭,设备标识符将保留,除非手动删除。

123
[AirBridge.state setDeviceAliasWithKey: "ADD_YOUR_KEY", value: "AND_YOUR_VALUE"];
[AirBridge.state removeDeviceAliasWithKey: "DELETE_THIS_KEY"];
[AirBridge.state clearDeviceAlias];

方法

说明

setDeviceAlias(withKey: String, value: String)

将键值对添加到设备标识符中。

removeDeviceAlias(withKey: String)

删除相应于 key 的设备标识符。如果没有相应的设备标识符,则不执行任何操作。

clearDeviceAlias()

删除所有设备标识符。

事件设置

当发生重要的用户行为时,您可以将该应用内事件发送至 Airbridge 分析。虽然事件参数是可选的,但建议添加更多参数,以便提供更准确的统计数据。

事件发送

您可使用 SDK 将服务内发生的各种事件发送至 Airbridge,以监测营销效果。

注意

事件参数重,setCategory 参数是必备项。

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

参数

说明

setCategory

事件名称 (必备)

setAction

事件属性 1

setLabel

事件属性 2

setValue

事件属性 3(值)

setSemantics

标准事件属性 (Map)

setCustoms

自定义事件属性

标准事件

注册(Sign-up)

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

登录(Sign-in)

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

退出登录(Sign-out)

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

ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.signOut];

[AirBridge.state setUser:[[ABUser alloc] init]];

查看首页(View Home Screen)

1234567
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
  
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.viewHome];

[event send];

查看搜索结果(View Search Result)

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

查看产品列表(View Product List)

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

查看产品详情(View Product Detail)

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

加入购物车(Add to Cart)

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

完成订单(Order Complete)

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

检查事件设置

1. 请通过 SDK 发送事件。

2. 请在 Airbridge 面板的 [原始数据]>[App 实时记录] 查看是否存在在步骤 1. 发送的事件。

高级设置

Restricted SDK

如果由于隐私法等原因无法收集 IDFA,您可以使用移除了 IDFA 收集功能的 Restricted SDK。Restricted SDK 从 1.34.9 版本开始支持。

CocoaPods 安装

1. 请使用以下命令创建 Podfile 文件:

12
cd path/to/project
touch Podfile

2. 请填充 Podfile 文件内容,如下所示:

Podfile
123
target '[Project Name]' do
    pod 'AirBridgeRestricted'
end

Airbridge iOS SDK 1.18.0 及以上版本需要 CocoaPods 1.11.0 及以上版本。

3. 请打开终端,输入以下命令:

12
cd path/to/project
pod install --repo-update

如果没有 pod 命令,请使用以下命令首先安装 CocoaPods:

  • sudo gem install cocoapods

直接安装

AirBridge.framework (Restricted) : 下载

SDK 签名(SDK Signature)设置

您可以通过设置 SDK 签名防止 SDK 伪造(SDK Spoofing)。请在 SDK 初始化代码之前调用 setSDKSignatureSecret 函数来更改设置。

12
[AirBridge setSDKSignatureSecretWithID: "YOUR_SDK_SIGNATURE_SECRET_ID", secret: "YOUR_SDK_SIGNATURE_SECRET"];
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];

为了设置 SDK 签名,需要 SDK 签名凭证。请参阅 本指南 获取 SDK 签名凭证。

停止用户标识符信息 SHA256 哈希处理设置

用户标识符信息中,User Email 和 User Phone 信息将自动进行哈希处理发送。您可以在 SDK 初始化代码之前调用 setIsUserInfoHashed 函数以停止哈希处理。

1234
// User 정보 Hash 화 해제
[AirBridge setIsUserInfoHashed:NO];

[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];

会话过期设置

您可以在 SDK 初始化代码之前调用 setSessionTimeout 函数,以在设定的会话期间内,即使用户重新启用 App,也可判断为同一个会话。

  • 会话过期时间的单位为毫秒(Millisecond),取值范围为从 0 到 604800000(7 天)。

  • 会话过期时间的默认值为 1000 * 60 * 5(5 分钟)。

123
[AirBridge setSessionTimeout:1000 * 60 * 5];

[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];

Opt-in 设置

此功能在根据隐私法(例:GDPRCCPA)收集和传输数据时需要征得用户同意的情况下非常有用。

如果在 SDK 初始化代码之前将 autoStartTrackingEnabled 设置为 false,则 SDK 在调用 startTracking 函数之前不会发送事件。

因此,如果在 App 关闭状态下发生 App 生命周期事件(例:深度链接打开),由于该事件可能在调用 startTracking 函数之前被发送,从而导致事件追踪不到。

12345
AirBridge.autoStartTrackingEnabled = NO;

[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];

[AirBridge startTracking];

默认情况下,当 App 通过深度链接打开时,SDK 会始终发送深度链接打开事件。如果在 SDK 初始化代码之前调用 setIsTrackAirbridgeDeeplinkOnly 函数并将其设置为 true,则只有通过 Airbridge 深度链接打开 App 时才会发送深度链接打开事件。

1234
// Airbridge 를 통한 딥링크 로 앱이 열린 경우에만 딥링크 이벤트를 전송
[AirBridge setIsTrackAirbridgeDeeplinkOnly:YES];

[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];

您可以通过以下设置使用 SDK 收取 Facebook 的 Deferred App Link。

1. 请参阅 Meta for Developers 指南 安装 Facebook SDK。

2. 请打开 ios/[Project 名称]/AppDelegate 文件。

3. 请在 SDK 初始化代码之前调用 setIsFacebookDeferredAppLinkEnabled 函数。

isFacebookDeferredAppLinkEnabled 设置为 YES、且已安装 Facebook SDK 时,SDK 将收取 Facebook Deferred App Link。

123
[AirBridge setIsFacebookDeferredAppLinkEnabled:YES];

[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];

App 卸载追踪设置

有关 App 卸载追踪,请参阅 本指南

推送通知深度链接追踪设置

当推送通知被点击时,请调用 handleNotificationDeeplink 函数,将推送通知 Payload 中的深度链接传递给 SDK。

1234567891011121314151617181920212223
- (void)application:(UIApplication *)application 
didReceiveRemoteNotification:(NSDictionary *)userInfo 
      fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler 
{
    if (UIApplication.sharedApplication.applicationState == UIApplicationStateInactive) {
        NSURL* url = // 푸시 알림 페이로드의 딥링크
        
        [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 = // 푸시 알림 페이로드의 딥링크
        
        [AirBridge.deeplink handleNotificationDeeplink:url];
    }
}

ATT 设置

根据 Apple 政策,iOS 14.5 及以上版本只有在通过 ATT (App Tracking Transparency, 应用跟踪透明度)弹出窗口 征得用户同意,才能收集 IDFA 信息。

12345
if (@available(iOS 14, *)) {
    [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
        NSLog(@"ATTrackingManagerAuthorizationStatus: %lu", (unsigned long)status);    
    }];
}

Tracking Authorize Timeout 设置

即使用户在 ATT 弹出窗口同意使用个人信息,由于在此之前安装事件已经被发送,因此安装事件不包含 IDFA。

如果在 SDK 初始化代码之前设置了 trackingAuthorizeTimeout,SDK 将在超时时间内延迟发送安装事件,等待用户在 ATT 弹窗中同意授权。

  • trackingAuthorizeTimeout 单位为毫秒(Millisecond)。

  • 安装事件发送可能有 trackingAuthorizeTimeout 长的延迟。

  • trackingAuthorizeTimeout 在每次重启 App 时都会被重置。

当用户在 ATT 弹窗做出选择或发生超时时,延迟深度链接将传递给回调函数。

为了避免每次重启 App 时重置超时,请将 isRestartTrackingAuthorizeTimeout 设置为 false

1234
AirBridge.setting.trackingAuthorizeTimeout = 30 * 1000;
AirBridge.setting.isRestartTrackingAuthorizeTimeout = NO;

[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];

注意

对于 1.32.1 及以上版本的 iOS SDK,trackingAuthorizeTimeout 的默认值为 30 秒。在实际应用时,请务必根据 App 的用户体验(UX)和 ATT 弹窗设置来调整该值。

事件缓冲限制设置

Airbridge SDK 具备在无法发送事件的情况下,将事件存储并重试发送的事件缓冲功能。通过设置事件缓冲限制,您可以限制用于存储此类事件的存储空间。设置的限制将在下次 SDK 初始化时生效。

1234
// Event count limit
[AirBridge.setting setEventMaximumBufferCount:newValue]
// Event size limit (Byte)
[AirBridge.setting setEventMaximumBufferSize:newValue]

事件发送周期设置

您可以设置 Airbridge SDK 发送事件的最小周期。当一次事件发送成功后,在下个周期到来前不会再次发送事件。默认的事件发送周期为 0 毫秒。

12
// 이벤트 전송 주기 (Millisecond 단위)
[AirBridge.setting setEventTransmitInterval:newValue]

未处理事件删除设置

为防止传输中的数据丢失,Airbridge SDK 会将未发送至服务器的事件存储在内部存储空间中。但是,如果启用此功能,Airbridge SDK 在初始化时会删除存储空间中的所有事件。

12345
// 활성화
Airbridge.setResetEventBufferEnabled(true)

// 비활성화
Airbridge.setResetEventBufferEnabled(false)

注意

此函数应在 Airbridge 开始追踪之前执行。即,当 autoStartTracking 设置为 true 时,应在调用 getInstance 之前执行;当 autoStartTracking 设置为 false 时,应在调用 startTracking 之前执行。否则,此功能将无法正常工作。

在 App 中使用追踪链接

Attention

如果在 Airbridge iOS SDK 1.24.0 及以上版本的 App 中使用追踪链接,将记录 “深度链接页面浏览(Deeplink Pageview)” 目标事件(Target Event)。如果深度链接页面浏览频繁随后深度链接打开(Deeplink Open)发生,可能会影响深度链接打开的绩效。

深度链接页面浏览的的默认归因窗口为 3 天。如果希望更改此归因窗口,请联系您的 CSM。

您可以通过以下设置使用户在 App 中跳转到同一 App 的另一个页面,无需通过外部浏览器。请注意,使用您自定义的链接短 ID 的追踪链接无法在 App 中使用。

12
Airbridge.placement().click("https://abr.ge/~~~")
Airbridge.placement().impression("https://abr.ge/~~~")

click

追踪链接被点击时调用,然后将点击计入点击统计,并将用户跳转到预先设置的 App 或 Web 目的地,或后备目的地。

impression

追踪链接被展示在用户界面(UI)时调用,然后将展示计入展示统计。

归因结果(Attribution Result)回调设置

您可以通过将回调闭包(Callback Closer)传递给 attributionCallback 收取归因结果数据。

归因结果回调仅在 App 安装后提供 1 次。

1234
AirBridge.setting().attributionCallback = { (attribution: [String : String]) in
    // Process attribution data...

}
  • 可以收取的数据如下:

字段

说明

attributedChannel

渠道(String)

attributedCampaign

广告系列(String)

attributedAdGroup

广告组(String)

attributedAdCreative

广告素材(String)

attributedContent

内容(String)

attributedTerm

关键词(String)

attributedSubPublisher

子渠道(String)

attributedSubSubPublisher1

二级子渠道 1(String)

attributedSubSubPublisher2

二级子渠道 2(String)

attributedSubSubPublisher3

二级子渠道 3(String)

  • 如果归因结果为无归因(Unattributed),attributedChannel 字段将收取 unattributed

123
  {
    "attributedChannel": "unattributed"
  }

归因结果数据使用指南

  • 有归因时:

  1. 在 SDK 初始化后的 40 秒内传递数据。

  2. 如果由于 App 关闭而未传递数据,则在下次 App 启用时,将在 SDK 初始化后的 40 秒内传递数据。

  3. 在极少数情况下,传递数据可能需要最多 5 分钟。

  • 无归因(Unattributed)时:

  1. 在 SDK 初始化至少 3 小时后 App 重新启用时,传递数据。

不建议在需要实时处理的情况下使用归因结果回调传递的数据。

会话中发生的生命周期事件收集设置

默认情况下,当 App 进入后台后在会话中发生的生命周期事件不会被收集。但是,如果启用此功能,这些事件将被收集。

1
[AirBridge.setting setTrackInSessionLifeCycleEventEnabled:YES];

Airbridge 停用设置

您可以通过以下设置停用 Airbridge 的所有功能:

12345
// 활성화
Airbridge.setSDKEnabled(true)

// 비활성화
Airbridge.setSDKEnabled(false)

Attention

此函数应在调用 Airbridge 初始化代码(getInstance)之前执行。否则,此功能将无法正常工作。

在 iOS Extension 收集事件

可以在 iOS Extension 使用 Airbridge SDK。请在 iOS Extension 的 viewDidLoad 函数初始化 SDK,然后使用  收集事件。

1234
override func viewDidLoad() {
  super.viewDidLoad()
    AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)
}

注意

在 iOS Extension 中使用 Airbridge SDK 时存在以下限制:

  • 在 iOS Extension 中,安装(Install)、打开(Open)、深度链接打开(Deeplink Open)、处于前台(Foreground)等生命周期事件不会被收集。

  • 在 iOS Extension 中发送事件时,如果进程被终止,事件不会被发送,将在下次 Extension 运行时(而非 App 启用时)重试发送。

  • 在 iOS Extension 中使用 Airbridge SDK 时,SKAN 转化值监测无法正常工作,因此请勿在 iOS Extension 中使用 SKAN 功能。

《数字市场法案》(DMA)遵守设置

为遵守《数字市场法案》(Digital Markets Act, 简称 DMA),用户的同意信息(User Consent)必须共享给 Airbridge。请注意,所有欧洲经济区(European Economic Area,简称 EEA)用户的同意信息应始终共享给 Airbridge。有关 DMA 的更多信息,请参阅 本指南

1. 请检查启用 App 的用户所在地。如果用户在 EEA(eea=1)启用了 App,则检查是否已取得该用户的同意信息。如果已取得,请继续步骤 3。

提示

Airbridge 无法提供有关存储用户同意信息或实现同意弹窗的指导。请咨询法律顾问。

2. 如果尚未取得用户的同意信息,请通过同意弹窗等方法取得用户的同意信息。必须收集 adPersonalizationadUserData

3. 请初始化 Airbridge Android SDK,并在收集用户信息之前将用户同意信息共享给 Airbridge。

注意

  • 必须为 eeaadPersonalizationadUserData 使用相同的名称。

  • 请根据收集的信息正确输入 01

1234567891011121314151617
// 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()
}

Hybrid App 设置

WebView 环境事件发送

iOS SDK 可以代替安装在 WebView 网站的 Web SDK 发送事件。请在 WebView 的 configuration 中的 controller 注入 AirBridge.webInterface

12345678
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];

YOUR_WEB_TOKEN 可在 Airbridge 面板的 [设置]>[Token] 获取。

故障排除

Webcredentials

当 App 使用 Autofill 功能保存密码时,如果没有设置 webcredentials:...,密码将被保存至 applinks:YOUR_APP_NAME.airbridge.io 或 applinks:YOUR_APP_NAME.abr.ge 域名中。

如果希望更改保存密码的域名,请将 example.com 更改为您希望使用的域名,并按照以下步骤进行设置:

1. 请将以下代码托管(host)至 https://example.com/.well-known/apple-app-site-association

12345
{
    "webcredentials": {
        "apps": ["TEAM_ID.APP_BUNDLE_ID"]
    }
}
  • 示例:9JA89QQLNQ.com.apple.wwdc

2. 请导航至 [Xcode]>[Project file]>[Signing & Capabilities]>[Associated Domains]。

3. 请点击 + 按钮添加 webcredentials:example.com

Bitcode 编译错误

从 Airbridge iOS SDK 1.28.0 版本起,停止支持 Bitcode(从 Xcode 14 起 Bitcode 已被弃用)。因此,如果在 App Project 使用 Bitcode,可以导致以下编译错误:

Text
1
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)

为了解决此问题,您可以在 podfile 文件中添加以下内容,或在 Xcode 将 ENABLE_BITCODE 设置为 NO

Podfile
12345
installer.pods_project.targets.each do |target|
    target.build_configurations.each do |configuration|
        configuration.build_settings['ENABLE_BITCODE'] = 'NO'
    end
end

Apple 的 App Store 已弃用 Bitcode,提交包含 Bitcode 的 .ipa 文件时将自动删除 Bitcode。

App 无法在 Xcode 13 构建

从 Airbridge iOS SDK 1.28.0 版本起,停止支持 Xcode 13 以及 iOS 9 和 10。如需使用这些版本,请使用 Airbridge iOS SDK 1.27.0 及以下版本。

同时使用 SPM 和 Tuist Fetch 安装时,在 iOS 14.2 以下版本发生冲突

Airbridge iOS SDK 使用多个 iOS 系统 Framework,其中 AdServices 要求 iOS 14.2 及以上版本。当 将链接的 Framework 所需最低 OS 版本 高于 Target 所需最低 OS 版本 时,SPM 可以自动以 Optional 链接,但是 Tuist Fetch(不使用 SPM,仅获取元数据取代 SPM 的操作)始终以 Required 链接。因此,同时使用 SPM 和 Tuist Fetch 安装时会发生冲突。

此问题可以通过按照 Tuist 提供的 Xcode Native Package Manager Support 方法 安装 SDK、或如下所示,手动下载并添加 AirBridge.xcframework 解决。

12345678
.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)

迁移指南

更新 SDK 时,请考虑以下内容:

1.36.0

对于 2023-09-04 或以后创建的 Airbridge App,1.34.0~1.35.1 版本中存在的深度链接回调提供的深度链接 URL 被解码 2 次的问题得到解决。

1.34.0

对于 2023-09-04 或以后创建的 Airbridge App,深度链接回调提供的深度链接 URL 中不再添加 airbridge_referrer

1.33.0

1.33.0 以下版本更新时,SKAN 转化值将以最后计算的值为准,不会进行额外计算。

  • 1.33.0 以下版本计算 SKAN 转化值的时间最多为 24 小时。

  • 对于新安装,这不会成为问题。

1.32.1

trackingAuthorizeTimeout 的默认值更改为 30 秒。

Was this page helpful?

Have any questions or suggestions?