注意
iOS SDK 1.35.1 以下版本存在已知问题。建议使用 1.35.1 及以上版本。
1. 请使用以下命令创建 Podfile
文件:
cd path/to/project
touch Podfile
2. 请填充 Podfile
文件内容,如下所示:
target '[Project Name]' do
pod 'AirBridge', '1.40.0'
end
Airbridge iOS SDK 1.18.0 及以上版本需要 CocoaPods 1.11.0 及以上版本。
3. 请打开终端,输入以下命令:
cd path/to/project
pod install --repo-update
如果没有 pod 命令,请使用以下命令首先安装 CocoaPods:
sudo gem install cocoapods
您可以通过 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 中。
请下载 AirBridge.framework。
请导航至 [Xcode]>[Project file]>[General]>[Frameworks, Libraries, and Embedded Content]>[+]。
请点击 [Add Other...]>[Add Files...] 添加在步骤1.下载的 AirBridge.xcframework 文件夹。
请将 AirBridge.xcframework 设置为 Embed & Sign。
请导航至 [Xcode]>[Project file]>[General]>[Frameworks, Libraries, and Embedded Content]>[+]。
请添加下方表格中的 5 个 Framework。
请将已添加的 5 个 Framework 设置为 Do not Embed。
请导航至 [Xcode]>[Project file]>[Build Phase]>[Link Binary with Libraries]。
请将 5 个 Framework 的 Status 设置为 Optional。
Framework | 说明 |
---|---|
AdSupport.framework | 用于收集 IDFA。 |
CoreTelephony.framework | 用于收集移动通讯运营商信息。 |
StoreKit.framework | 用于收集 SKAN 信息。 |
AppTrackingTransparency.framework | 用于收集 ATT 同意状态信息。 |
AdServices.framework | 由于收集 Apple Search Ads 归因信息(iOS 14.3 及以上)。 |
请将以下代码添加至 AppDelegate 的 application(_:didFinishLaunchingWithOptions:)
顶部以初始化 SDK。
#import <AirBridge/AirBridge.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
...
}
import AirBridge
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)
// ...
}
如果使用 AppDelegate 不存在的 SwiftUI 环境,请在 @main
存在的 App 类初始化 SDK。
// YourprojectApp.swift
import SwiftUI
import AirBridge
@main
struct OnlyUIApp: App {
init() {
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName: "YOUR_APP_NAME")
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
YOUR_APP_NAME
和 YOUR_APP_SDK_TOKEN
可在 Airbridge 面板的 [设置] >[Token] 获取。
为了使用 iOS SDK,需要在应用商店发布 App 时接受《IDFA 条款》。
请在 “Does this app use the Advertising Identifier (IDFA)?” 项目勾选 “Yes”。
请勾选 “Attribute this app installation to a previously served advertisement.” 项目。
请勾选 “Attribute an action taken within this app to a previously served advertisement.” 项目。
请勾选 “Limit Ad Tracking setting in iOS" 同意项目。
请查看安装并启用 App 时,安装(Install)事件是否收集到。
从 SDK 发生的事件可在 Airbridge 面板的 [原始数据]>[App 实时记录] 查看。
1. 请导航至 Airbridge 面板的 [原始数据]>[App 实时记录]。
2. 请在搜索栏中输入已安装并启用 App 的设备的 IDFA。实时记录最多可能会有 5 分钟的延迟。
请在 SDK 初始化代码顶部输入以下代码以输出 SDK Log:
[AirBridge setLogLevel:AB_LOG_ALL];
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
AirBridge.setLogLevel(.LOG_ALL)
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)
请在 Airbridge 面板的 [追踪链接]>[深度链接] 注册 2 项信息:
iOS URI Scheme
iOS App ID
请在 iOS URI Scheme 输入栏输入您的 iOS URI Scheme,包括 ://
。
注意
请为已发布或即将发布的 App 和开发用的 App 注册不同的 URI Scheme。
如果已发布或即将发布的 App 与开发用的 App 具有相同的 URI Scheme,深度链接可能会打开意外的 App。
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
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]。
支持 iOS 12 及以下版本的 App 通常在 AppDelegate 的 application(_:open:options:)
方法中传递事件。
1. 请打开 ios/[Project 名称]/AppDelegate
文件。
2. 请在以下函数顶部调用 handleURLSchemeDeeplink
函数,以便当 App 通过 Scheme 打开时,将深度链接信息传递给 SDK:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id>*)options
{
[AirBridge.deeplink handleURLSchemeDeeplink:url];
return YES;
}
func application(_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool
{
AirBridge.deeplink()?.handleURLSchemeDeeplink(url)
return true
}
3. 请在以下函数顶部调用 handleUserActivity
函数,以便当 App 通过 Universal Link 打开时,将深度链接信息传递给 SDK:
- (BOOL)application:(UIApplication*)application
continueUserActivity:(NSUserActivity*)userActivity
restorationHandler:(void (^)(NSArray* _Nullable))restorationHandler
{
[AirBridge.deeplink handleUserActivity:userActivity];
return YES;
}
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool
{
AirBridge.deeplink()?.handle(userActivity)
return true
}
Attention
使用 SceneDelegate 的 Project 将通过 SceneDelegate 传递 URL,而非通过 AppDelegate。有关通过 SceneDelegate 收取 URL 的方法,请参阅下方的 "使用 SceneDelegate 时" 部分。
支持 iOS 13 及以上版本的 App 中,如果使用 SceneDelegate,将通过以下方法传递深度链接:
App 在 Not Running 状态下加载时:scene(_:willConnectTo:options:)
在所有其他情况下(例:Background 状态)
Universal Link:scene(_:continue:)
Scheme Link:scene(_:openURLContexts:)
import UIKit
import AirBridge
@available(iOS 13, *)
class SceneDelegate: UIWindowSceneDelegate {
var window: UIWindow?
// Receive links after the app's killed
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let schemeLinkURL = connectionOptions.urlContexts.first?.url {
// Scheme
AirBridge.deeplink()?.handleURLSchemeDeeplink(schemeLinkURL)
} else if let userActivity = connectionOptions.userActivities.first {
// Universal
AirBridge.deeplink()?.handle(userActivity)
}
// ...
}
// Receive universal link
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
AirBridge.deeplink().handle(userActivity)
// ...
}
// Receive scheme link
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
guard let schemeLinkURL = URLContexts.first?.url else {
return
}
AirBridge.deeplink().handleURLSchemeDeeplink(schemeLinkURL)
// ...
}
}
如果使用不具有 SceneDelegate 的 SwiftUI,深度链接将通过 onOpenUrl
传递。请在 @main
存在的 App 类添加此方法。
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 时” 部分。
1. 请打开 ios/[Project 名称]/AppDelegate
文件。
2. 请在 AppDelegate 的 application(_:didFinishLaunchingWithOptions:)
使用 setDeeplinkCallback
函数设置回调,以便在 App 通过深度链接打开时调用。
- (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);
}];
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey:
Any]?) -> Bool {
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName: "YOUR_APP_NAME", withLaunchOptions: launchOptions)
AirBridge.deeplink()?.setDeeplinkCallback({ deeplink in
// 딥링크로 앱이 열리는 경우 작동할 코드
// Airbridge 를 통한 Deeplink = YOUR_SCHEME://...
NSLog("DeeplinkCallback : %@", deeplink)
})
return true
}
请在 @main
存在的 App 类添加相应的方法:
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://...
格式传递。
如果设置深度链接回调,延迟深度链接信息也将通过同样的深度链接回调传递。有关延迟深度链接回调设置,请参阅 深度链接回调(Deep Link Callback)设置。
延迟深度链接回调仅在 App 安装后提供 1 次。
1. 请点击在 Airbridge 面板注册的 YOUR_SCHEME://...
格式的 iOS URI Scheme。
2. 请检查是否打开了正确的 App 页面、并且在 Airbridge 面板的 [原始数据]>[App 实时记录] 存在深度链接打开(Deeplink Open)事件。
您可在 SDK 中设置用户标识符,使以后收集的所有事件包含用户标识符。
[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"];
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()?.addUserAlias(withKey: "key", value: "value")
名称 | 说明 | 限制 |
---|---|---|
id | 用户 ID | - |
用户邮箱 | 将自动进行 SHA256 哈希处理(可选停用) | |
phone | 用户电话号码 | 将自动进行 SHA256 哈希处理(可选停用) |
alias | 可以代表用户的其他 ID | - 最多可设置 10 个。 |
您可以为提高 MTA(Multi-touch attribution, 多触点归因)分析的准确性、内部数据分析以及与第三方解决方案的集成等目的设置附加用户属性。
// 입력된 dictionary 로 user attributes 가 교체됩니다.
[AirBridge.state setUserAttributes:@{@"key": @"value"}];
// 기존의 user attributes 에 해당 key, value 가 추가됩니다.
[AirBridge.state addUserAttributesWithKey:@"key" value:@"value"];
// 입력된 dictionary 로 user attributes 가 교체됩니다.
AirBridge.state()?.setUserAttributes(["key": "value" as NSObject])
// 기존의 user attributes 에 해당 key, value 가 추가됩니다.
AirBridge.state()?.addUserAttributes(withKey: "key", value: "value" as NSObject)
名称 | 说明 | 限制 |
---|---|---|
attribute | 用户属性 | - 最多可设置 100 个。 |
1. 请完成用户设置。
2. 请通过 SDK 发送事件。
3. 请在 Airbridge 面板的 [原始数据]>[App 实时记录] 搜索并点击在步骤 2. 发送的事件,查看是否在 JSON 的 user
部分包含已设置的用户信息。
您可在 SDK 中设置设备标识符,使以后收集的所有事件包含设备标识符。设置后,无论 App 是否关闭,设备标识符将保留,除非手动删除。
[AirBridge.state setDeviceAliasWithKey: "ADD_YOUR_KEY", value: "AND_YOUR_VALUE"];
[AirBridge.state removeDeviceAliasWithKey: "DELETE_THIS_KEY"];
[AirBridge.state clearDeviceAlias];
AirBridge.state()?.setDeviceAlias(key: "ADD_YOUR_KEY", value: "AND_YOUR_VALUE")
AirBridge.state()?.removeDeviceAlias(key: "DELETE_THIS_KEY")
AirBridge.state().clearDeviceAlias()
方法 | 说明 |
---|---|
setDeviceAlias(withKey: String, value: String) | 将键值对添加到设备标识符中。 |
removeDeviceAlias(withKey: String) | 删除相应于 key 的设备标识符。如果没有相应的设备标识符,则不执行任何操作。 |
clearDeviceAlias() | 删除所有设备标识符。 |
当发生重要的用户行为时,您可以将该应用内事件发送至 Airbridge 分析。虽然事件参数是可选的,但建议添加更多参数,以便提供更准确的统计数据。
您可使用 SDK 将服务内发生的各种事件发送至 Airbridge,以监测营销效果。
注意
事件参数重,
setCategory
参数是必备项。
#import <AirBridge/ABInAppEvent.h>
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:@"category"];
[event setAction:@"action"];
[event setLabel:@"label"];
[event setValue:@(123)];
[event setCustoms:@{@"key": @"value"}];
// Semantic Attributes Option 1
ABSemanticAttributes* semanticAttributes = [[ABSemanticAttributes alloc] init];
semanticAttributes.transactionID = @"transaction_123";
[event setSemanticAttributes:semanticAttributes];
// Semantic Attributes Option 2
// For more details, please check following page
// https://developers.airbridge.io/docs/event-structure#semantic-attributes
[event setSemantics:@{@"transactionID": @"transaction_123"}];
[event send];
let event = ABInAppEvent()
event?.setCategory("category")
event?.setAction("action")
event?.setLabel("label")
event?.setValue(123)
event?.setCustoms(["key": "value"])
// Semantic Attributes Option 1
let semanticAttributes = ABSemanticAttributes()
semanticAttributes?.transactionID = "transaction_123"
event?.setSemanticAttributes(semanticAttributes)
// Semantic Attributes Option 2
// For more details, please check following page
// https://developers.airbridge.io/docs/event-structure#semantic-attributes
event?.setSemantics(["transactionID": "transaction_123"])
event?.send()
参数 | 说明 |
---|---|
setCategory | 事件名称 (必备) |
setAction | 事件属性 1 |
setLabel | 事件属性 2 |
setValue | 事件属性 3(值) |
setSemantics | 标准事件属性 (Map) |
setCustoms | 自定义事件属性 |
#import <AirBridge/ABUser.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
ABUser* user = [[ABUser alloc] init];
user.ID = @"testID";
user.email = @"testID@ab180.co";
user.phone = @"000-0000-0000";
user.alias = @{
@"key": @"value",
};
user.attributes = @{
@"key": @"value",
};
[AirBridge.state setUser:user];
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.signUp];
[event send];
let user = ABUser()
user.id = "testID"
user.email = "testID@ab180.co"
user.phone = "000-0000-0000"
user.attributes = [
"key": "value" as NSObject,
]
user.alias = [
"key": "value",
]
AirBridge.state().setUser(user)
let event = ABInAppEvent()
event?.setCategory(ABCategory.signUp)
event?.send()
#import <AirBridge/ABUser.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
ABUser* user = [[ABUser alloc] init];
user.ID = @"testID";
user.email = @"testID@ab180.co";
user.phone = @"000-0000-0000";
user.alias = @{
@"key": @"value",
};
user.attributes = @{
@"key": @"value",
};
[AirBridge.state setUser:user];
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.signIn];
[event send];
let user = ABUser()
user.id = "testID"
user.email = "testID@ab180.co"
user.phone = "000-0000-0000"
user.attributes = [
"key": "value" as NSObject,
]
user.alias = [
"key": "value",
]
AirBridge.state().setUser(user)
let event = ABInAppEvent()
event?.setCategory(ABCategory.signIn)
event?.send()
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.signOut];
[AirBridge.state setUser:[[ABUser alloc] init]];
let event = ABInAppEvent()
event?.setCategory(ABCategory.signOut)
event?.send()
AirBridge.state().setUser(ABUser())
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.viewHome];
[event send];
let event = ABInAppEvent()
event?.setCategory(ABCategory.viewHome)
event?.send()
#import <AirBridge/ABProduct.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
#import <AirBridge/ABSemanticsKey.h>
ABProduct* product1 = [[ABProduct alloc] init];
product1.idx = @"idx1";
product1.name = @"name1";
product1.price = @100;
product1.currency = @"USD";
product1.orderPosition = @1;
product1.quantity = @1;
ABProduct* product2 = [[ABProduct alloc] init];
product2.idx = @"idx2";
product2.name = @"name2";
product2.price = @200;
product2.currency = @"USD";
product2.orderPosition = @2;
product2.quantity = @2;
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.viewSearchResult];
[event setSemantics:@{
ABSemanticsKey.products: @[
product1.toDictionary,
product2.toDictionary,
],
ABSemanticsKey.query: @"query",
}];
[event send];
let product1 = ABProduct()
product1.idx = "idx1"
product1.name = "name1"
product1.price = 100
product1.currency = "USD"
product1.orderPosition = 1
product1.quantity = 1
let product2 = ABProduct()
product2.idx = "idx2"
product2.name = "name2"
product2.price = 200
product2.currency = "USD"
product2.orderPosition = 2
product2.quantity = 2
let event = ABInAppEvent()
event?.setCategory(ABCategory.viewSearchResult)
event?.setSemantics([
ABSemanticsKey.products: [
product1.toDictionary(),
product2.toDictionary(),
],
ABSemanticsKey.query: "query",
])
event?.send()
#import <AirBridge/ABProduct.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
#import <AirBridge/ABSemanticsKey.h>
ABProduct* product1 = [[ABProduct alloc] init];
product1.idx = @"idx1";
product1.name = @"name1";
product1.price = @100;
product1.currency = @"USD";
product1.orderPosition = @1;
product1.quantity = @1;
ABProduct* product2 = [[ABProduct alloc] init];
product2.idx = @"idx2";
product2.name = @"name2";
product2.price = @200;
product2.currency = @"USD";
product2.orderPosition = @2;
product2.quantity = @2;
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.viewProductList];
[event setSemantics:@{
ABSemanticsKey.products: @[
product1.toDictionary,
product2.toDictionary,
],
ABSemanticsKey.productListID: @"listID",
}];
[event send];
let product1 = ABProduct()
product1.idx = "idx1"
product1.name = "name1"
product1.price = 100
product1.currency = "USD"
product1.orderPosition = 1
product1.quantity = 1
let product2 = ABProduct()
product2.idx = "idx2"
product2.name = "name2"
product2.price = 200
product2.currency = "USD"
product2.orderPosition = 2
product2.quantity = 2
let event = ABInAppEvent()
event?.setCategory(ABCategory.viewProductList)
event?.setSemantics([
ABSemanticsKey.products: [
product1.toDictionary(),
product2.toDictionary(),
],
ABSemanticsKey.productListID: "productListID",
])
event?.send()
#import <AirBridge/ABProduct.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
#import <AirBridge/ABSemanticsKey.h>
ABProduct* product1 = [[ABProduct alloc] init];
product1.idx = @"idx1";
product1.name = @"name1";
product1.price = @100;
product1.currency = @"USD";
product1.orderPosition = @1;
product1.quantity = @1;
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.viewProductDetail];
[event setSemantics:@{
ABSemanticsKey.products: @[product1.toDictionary],
}];
[event send];
let product1 = ABProduct()
product1.idx = "idx1"
product1.name = "name1"
product1.price = 100
product1.currency = "USD"
product1.orderPosition = 1
product1.quantity = 1
let event = ABInAppEvent()
event?.setCategory(ABCategory.viewProductDetail)
event?.setSemantics([
ABSemanticsKey.products: [
product1.toDictionary(),
],
])
event?.send()
#import <AirBridge/ABProduct.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
#import <AirBridge/ABSemanticsKey.h>
ABProduct* product1 = [[ABProduct alloc] init];
product1.idx = @"idx1";
product1.name = @"name1";
product1.price = @100;
product1.currency = @"USD";
product1.orderPosition = @1;
product1.quantity = @1;
ABProduct* product2 = [[ABProduct alloc] init];
product2.idx = @"idx2";
product2.name = @"name2";
product2.price = @200;
product2.currency = @"USD";
product2.orderPosition = @2;
product2.quantity = @2;
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.addToCart];
[event setSemantics:@{
ABSemanticsKey.products: @[
product1.toDictionary,
product2.toDictionary,
],
ABSemanticsKey.cartID: @"cartID",
ABSemanticsKey.currency: @"currency"
}];
[event setValue:@300];
[event send];
let product1 = ABProduct()
product1.idx = "idx1"
product1.name = "name1"
product1.price = 100
product1.currency = "USD"
product1.orderPosition = 1
product1.quantity = 1;
let product2 = ABProduct()
product2.idx = "idx2"
product2.name = "name2"
product2.price = 200
product2.currency = "USD"
product2.orderPosition = 2
product2.quantity = 2;
let event = ABInAppEvent()
event?.setCategory(ABCategory.addToCart)
event?.setSemantics([
ABSemanticsKey.products: [
product1.toDictionary(),
product2.toDictionary(),
],
ABSemanticsKey.cartID: "cartID",
ABSemanticsKey.currency: "KRW",
])
event.setValue(300)
event?.send()
#import <AirBridge/ABProduct.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
#import <AirBridge/ABSemanticsKey.h>
ABProduct* product1 = [[ABProduct alloc] init];
product1.idx = @"coke_zero";
product1.name = @"Coke Zero";
product1.price = @100;
product1.currency = @"USD";
product1.orderPosition = @1;
product1.quantity = @1;
ABProduct* product2 = [[ABProduct alloc] init];
product2.idx = @"burger_cheese_double";
product2.name = @"Double Cheeseburger";
product2.price = @200;
product2.currency = @"USD";
product2.orderPosition = @2;
product2.quantity = @2;
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.purchase];
[event setSemantics:@{
ABSemanticsKey.products: @[
product1.toDictionary,
product2.toDictionary,
],
ABSemanticsKey.transcationID: @"transcationID",
ABSemanticsKey.currency: @"currency",
ABSemanticsKey.inAppPurchased: @YES
}];
[event setValue:@300];
[event send];
let product1 = ABProduct()
product1.idx = "coke_zero"
product1.name = "Coke Zero"
product1.price = 100
product1.currency = "USD"
product1.orderPosition = 1
product1.quantity = 1
let product2 = ABProduct()
product2.idx = "burger_cheese_double"
product2.name = "Double Cheeseburger"
product2.price = 200
product2.currency = "USD"
product2.orderPosition = 2
product2.quantity = 2
let event = ABInAppEvent()
event?.setCategory(ABCategory.purchase)
event?.setSemantics([
ABSemanticsKey.products: [
product1.toDictionary(),
product2.toDictionary(),
],
ABSemanticsKey.transactionID: "transactionID",
ABSemanticsKey.currency: "KRW",
ABSemanticsKey.inAppPurchased: true
])
event?.setValue(300)
event?.send()
1. 请通过 SDK 发送事件。
2. 请在 Airbridge 面板的 [原始数据]>[App 实时记录] 查看是否存在在步骤 1. 发送的事件。
如果由于隐私法等原因无法收集 IDFA,您可以使用移除了 IDFA 收集功能的 Restricted SDK。Restricted SDK 从 1.34.9 版本开始支持。
1. 请使用以下命令创建 Podfile
文件:
cd path/to/project
touch Podfile
2. 请填充 Podfile
文件内容,如下所示:
target '[Project Name]' do
pod 'AirBridgeRestricted'
end
Airbridge iOS SDK 1.18.0 及以上版本需要 CocoaPods 1.11.0 及以上版本。
3. 请打开终端,输入以下命令:
cd path/to/project
pod install --repo-update
如果没有 pod 命令,请使用以下命令首先安装 CocoaPods:
sudo gem install cocoapods
AirBridge.framework (Restricted) : 下载
您可以通过设置 SDK 签名防止 SDK 伪造(SDK Spoofing)。请在 SDK 初始化代码之前调用 setSDKSignatureSecret
函数来更改设置。
[AirBridge setSDKSignatureSecretWithID: "YOUR_SDK_SIGNATURE_SECRET_ID", secret: "YOUR_SDK_SIGNATURE_SECRET"];
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
AirBridge.setSDKSignatureSecret(id: "YOUR_SDK_SIGNATURE_SECRET_ID", secret: "YOUR_SDK_SIGNATURE_SECRET")
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)
为了设置 SDK 签名,需要 SDK 签名凭证。请参阅 本指南 获取 SDK 签名凭证。
用户标识符信息中,User Email 和 User Phone 信息将自动进行哈希处理发送。您可以在 SDK 初始化代码之前调用 setIsUserInfoHashed
函数以停止哈希处理。
// User 정보 Hash 화 해제
[AirBridge setIsUserInfoHashed:NO];
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
// User 정보 Hash 화 해제
AirBridge.setIsUserInfoHashed(false)
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)
您可以在 SDK 初始化代码之前调用 setSessionTimeout
函数,以在设定的会话期间内,即使用户重新启用 App,也可判断为同一个会话。
会话过期时间的单位为毫秒(Millisecond),取值范围为从 0 到 604800000(7 天)。
会话过期时间的默认值为 1000 * 60 * 5
(5 分钟)。
[AirBridge setSessionTimeout:1000 * 60 * 5];
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
AirBridge.setSessionTimeout(1000 * 60 * 5)
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)
此功能在根据隐私法(例:GDPR、CCPA)收集和传输数据时需要征得用户同意的情况下非常有用。
如果在 SDK 初始化代码之前将 autoStartTrackingEnabled
设置为 false
,则 SDK 在调用 startTracking
函数之前不会发送事件。
因此,如果在 App 关闭状态下发生 App 生命周期事件(例:深度链接打开),由于该事件可能在调用 startTracking
函数之前被发送,从而导致事件追踪不到。
AirBridge.autoStartTrackingEnabled = NO;
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
[AirBridge startTracking];
AirBridge.setAutoStartTrackingEnabled(false)
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)
AirBridge.startTracking()
默认情况下,当 App 通过深度链接打开时,SDK 会始终发送深度链接打开事件。如果在 SDK 初始化代码之前调用 setIsTrackAirbridgeDeeplinkOnly
函数并将其设置为 true
,则只有通过 Airbridge 深度链接打开 App 时才会发送深度链接打开事件。
// Airbridge 를 통한 딥링크 로 앱이 열린 경우에만 딥링크 이벤트를 전송
[AirBridge setIsTrackAirbridgeDeeplinkOnly:YES];
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
// Airbridge 를 통한 딥링크 로 앱이 열린 경우에만 딥링크 이벤트를 전송
AirBridge.setIsTrackAirbridgeDeeplinkOnly(true)
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。
[AirBridge setIsFacebookDeferredAppLinkEnabled:YES];
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
AirBridge.setIsFacebookDeferredAppLinkEnabled(true)
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName: "YOUR_APP_NAME", withLaunchOptions: launchOptions)
有关 App 卸载追踪,请参阅 本指南。
当推送通知被点击时,请调用 handleNotificationDeeplink
函数,将推送通知 Payload 中的深度链接传递给 SDK。
- (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];
}
}
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable : Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)
{
if UIApplication.shared.applicationState == .inactive {
let url = // 푸시 알림 페이로드의 딥링크
AirBridge.deeplink()?.handleNotificationDeeplink(url)
}
}
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse, withCompletionHandler
completionHandler: @escaping () -> Void)
{
if UIApplication.shared.applicationState == .inactive || UIApplication.shared.applicationState == .background,
response.actionIdentifier == UNNotificationDefaultActionIdentifier
{
let url = // 푸시 알림 페이로드의 딥링크
AirBridge.deeplink()?.handleNotificationDeeplink(url)
}
}
根据 Apple 政策,iOS 14.5 及以上版本只有在通过 ATT (App Tracking Transparency, 应用跟踪透明度)弹出窗口 征得用户同意,才能收集 IDFA 信息。
if (@available(iOS 14, *)) {
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
NSLog(@"ATTrackingManagerAuthorizationStatus: %lu", (unsigned long)status);
}];
}
if #available(iOS 14, *) {
ATTrackingManager.requestTrackingAuthorization { status in
print(status.rawValue)
}
}
即使用户在 ATT 弹出窗口同意使用个人信息,由于在此之前安装事件已经被发送,因此安装事件不包含 IDFA。
如果在 SDK 初始化代码之前设置了 trackingAuthorizeTimeout
,SDK 将在超时时间内延迟发送安装事件,等待用户在 ATT 弹窗中同意授权。
trackingAuthorizeTimeout
单位为毫秒(Millisecond)。
安装事件发送可能有 trackingAuthorizeTimeout
长的延迟。
trackingAuthorizeTimeout
在每次重启 App 时都会被重置。
当用户在 ATT 弹窗做出选择或发生超时时,延迟深度链接将传递给回调函数。
为了避免每次重启 App 时重置超时,请将 isRestartTrackingAuthorizeTimeout
设置为 false
。
AirBridge.setting.trackingAuthorizeTimeout = 30 * 1000;
AirBridge.setting.isRestartTrackingAuthorizeTimeout = NO;
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
AirBridge.setting()?.trackingAuthorizeTimeout = 30 * 1000
AirBridge.setting()?.isRestartTrackingAuthorizeTimeout = false
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)
注意
对于 1.32.1 及以上版本的 iOS SDK,
trackingAuthorizeTimeout
的默认值为 30 秒。在实际应用时,请务必根据 App 的用户体验(UX)和 ATT 弹窗设置来调整该值。
Airbridge SDK 具备在无法发送事件的情况下,将事件存储并重试发送的事件缓冲功能。通过设置事件缓冲限制,您可以限制用于存储此类事件的存储空间。设置的限制将在下次 SDK 初始化时生效。
// Event count limit
[AirBridge.setting setEventMaximumBufferCount:newValue]
// Event size limit (Byte)
[AirBridge.setting setEventMaximumBufferSize:newValue]
// Event count limit
AirBridge.setting().setEventMaximumBufferCount(newValue)
// Event size limit (Byte)
AirBridge.setting().setEventMaximumBufferSize(newValue)
您可以设置 Airbridge SDK 发送事件的最小周期。当一次事件发送成功后,在下个周期到来前不会再次发送事件。默认的事件发送周期为 0 毫秒。
// 이벤트 전송 주기 (Millisecond 단위)
[AirBridge.setting setEventTransmitInterval:newValue]
// 이벤트 전송 주기 (Millisecond 단위)
AirBridge.setting().setEventTransmitInterval(newValue)
为防止传输中的数据丢失,Airbridge SDK 会将未发送至服务器的事件存储在内部存储空间中。但是,如果启用此功能,Airbridge SDK 在初始化时会删除存储空间中的所有事件。
// 활성화
Airbridge.setResetEventBufferEnabled(true)
// 비활성화
Airbridge.setResetEventBufferEnabled(false)
注意
此函数应在 Airbridge 开始追踪之前执行。即,当
autoStartTracking
设置为true
时,应在调用getInstance
之前执行;当autoStartTracking
设置为false
时,应在调用startTracking
之前执行。否则,此功能将无法正常工作。
Attention
如果在 Airbridge iOS SDK 1.24.0 及以上版本的 App 中使用追踪链接,将记录 “深度链接页面浏览(Deeplink Pageview)” 目标事件(Target Event)。如果深度链接页面浏览频繁随后深度链接打开(Deeplink Open)发生,可能会影响深度链接打开的绩效。
深度链接页面浏览的的默认归因窗口为 3 天。如果希望更改此归因窗口,请联系您的 CSM。
您可以通过以下设置使用户在 App 中跳转到同一 App 的另一个页面,无需通过外部浏览器。请注意,使用您自定义的链接短 ID 的追踪链接无法在 App 中使用。
Airbridge.placement().click("https://abr.ge/~~~")
Airbridge.placement().impression("https://abr.ge/~~~")
追踪链接被点击时调用,然后将点击计入点击统计,并将用户跳转到预先设置的 App 或 Web 目的地,或后备目的地。
追踪链接被展示在用户界面(UI)时调用,然后将展示计入展示统计。
您可以通过将回调闭包(Callback Closer)传递给 attributionCallback
收取归因结果数据。
归因结果回调仅在 App 安装后提供 1 次。
AirBridge.setting().attributionCallback = { (attribution: [String : String]) in
// Process attribution data...
}
[AirBridge.setting setAttributionCallback:^(NSDictionary<NSString *,NSString *> * _Nonnull attribution) {
// 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
。
{
"attributedChannel": "unattributed"
}
归因结果数据使用指南
有归因时:
在 SDK 初始化后的 40 秒内传递数据。
如果由于 App 关闭而未传递数据,则在下次 App 启用时,将在 SDK 初始化后的 40 秒内传递数据。
在极少数情况下,传递数据可能需要最多 5 分钟。
无归因(Unattributed)时:
在 SDK 初始化至少 3 小时后 App 重新启用时,传递数据。
不建议在需要实时处理的情况下使用归因结果回调传递的数据。
默认情况下,当 App 进入后台后在会话中发生的生命周期事件不会被收集。但是,如果启用此功能,这些事件将被收集。
[AirBridge.setting setTrackInSessionLifeCycleEventEnabled:YES];
AirBridge.setting().setTrackInSessionLifeCycleEventEnabled(true)
您可以通过以下设置停用 Airbridge 的所有功能:
// 활성화
Airbridge.setSDKEnabled(true)
// 비활성화
Airbridge.setSDKEnabled(false)
Attention
此函数应在调用 Airbridge 初始化代码(
getInstance
)之前执行。否则,此功能将无法正常工作。
可以在 iOS Extension 使用 Airbridge SDK。请在 iOS Extension 的 viewDidLoad
函数初始化 SDK,然后使用 收集事件。
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 功能。
为遵守《数字市场法案》(Digital Markets Act, 简称 DMA),用户的同意信息(User Consent)必须共享给 Airbridge。请注意,所有欧洲经济区(European Economic Area,简称 EEA)用户的同意信息应始终共享给 Airbridge。有关 DMA 的更多信息,请参阅 本指南。
1. 请检查启用 App 的用户所在地。如果用户在 EEA(eea=1
)启用了 App,则检查是否已取得该用户的同意信息。如果已取得,请继续步骤 3。
提示
Airbridge 无法提供有关存储用户同意信息或实现同意弹窗的指导。请咨询法律顾问。
2. 如果尚未取得用户的同意信息,请通过同意弹窗等方法取得用户的同意信息。必须收集 adPersonalization
和 adUserData
。
注意
从 2024-03-06 起,必须对 EEA 的现有用户和新用户至少收集一次同意信息。
必须共享给 Airbridge 的用户同意信息如下。eea
值不是用户的直接响应,也不是 Airbridge 自动收集的信息。请根据用户所在地确定 eea
值并将其共享给 Airbridge。
Airbridge 字段 |
Google 字段 |
说明 |
---|---|---|
<string> |
| 表示用户是否在 EEA,或 DMA 适用地区。该值不是用户的直接响应,也不是 Airbridge 自动收集的信息。请根据用户所在地确定 不处理除 - - |
<string> |
| 对于收集信息以提供个性化广告(Personalized Ads) 的用户同意情况。不处理除 - - |
<string> |
| 对于向 Google 发送用于广告目的用户数据的同意情况。不处理除 - - |
3. 请初始化 Airbridge Android SDK,并在收集用户信息之前将用户同意信息共享给 Airbridge。
注意
必须为
eea
、adPersonalization
和adUserData
使用相同的名称。请根据收集的信息正确输入
0
或1
。
// AppDelegate.swift
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]?
) {
AirBridge.setAutoStartTrackingEnabled(false)
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)
// Based on actual region
AirBridge.state()?.UserAlias(withKey:"eea", value:"0" or "1")
// Based on actual user consent
AirBridge.state()?.UserAlias(withKey:"adPersonalization", value:"0" or "1")
AirBridge.state()?.UserAlias(withKey:"adUserData", value:"0" or "1")
AirBridge.startTracking()
}
// AppDelegate.m
- (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
AirBridge.autoStartTrackingEnabled = NO;
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
// Based on actual region
[AirBridge.state addUserAliasWithKey:@"eea" value:"0" or "1"];
// Based on actual user consent
[AirBridge.state addUserAliasWithKey:@"adPersonalization" value:"0" or "1"];
[AirBridge.state addUserAliasWithKey:@"adUserData" value:"0" or "1"];
[AirBridge startTracking];
}
iOS SDK 可以代替安装在 WebView 网站的 Web SDK 发送事件。请在 WebView 的 configuration
中的 controller
注入 AirBridge.webInterface
。
WKWebViewConfiguration* configuration = [[WKWebViewConfiguration alloc] init];
WKUserContentController* controller = [[WKUserContentController alloc] init];
[AirBridge.webInterface injectTo:controller withWebToken:@"YOUR_WEB_TOKEN"];
configuration.userContentController = controller;
WKWebView* webview = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
let configuration = WKWebViewConfiguration()
let controller = WKUserContentController()
AirBridge.webInterface()?.inject(to: controller, withWebToken: "YOUR_WEB_TOKEN")
configuration.userContentController = controller
webView = WKWebView(frame: .zero, configuration: configuration)
YOUR_WEB_TOKEN
可在 Airbridge 面板的 [设置]>[Token] 获取。
当 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
。
{
"webcredentials": {
"apps": ["TEAM_ID.APP_BUNDLE_ID"]
}
}
示例:9JA89QQLNQ.com.apple.wwdc
2. 请导航至 [Xcode]>[Project file]>[Signing & Capabilities]>[Associated Domains]。
3. 请点击 +
按钮添加 webcredentials:example.com
。
从 Airbridge iOS SDK 1.28.0 版本起,停止支持 Bitcode(从 Xcode 14 起 Bitcode 已被弃用)。因此,如果在 App Project 使用 Bitcode,可以导致以下编译错误:
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
。
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。
从 Airbridge iOS SDK 1.28.0 版本起,停止支持 Xcode 13 以及 iOS 9 和 10。如需使用这些版本,请使用 Airbridge iOS SDK 1.27.0 及以下版本。
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 解决。
.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 时,请考虑以下内容:
对于 2023-09-04 或以后创建的 Airbridge App,1.34.0~1.35.1 版本中存在的深度链接回调提供的深度链接 URL 被解码 2 次的问题得到解决。
对于 2023-09-04 或以后创建的 Airbridge App,深度链接回调提供的深度链接 URL 中不再添加 airbridge_referrer
。
1.33.0 以下版本更新时,SKAN 转化值将以最后计算的值为准,不会进行额外计算。
1.33.0 以下版本计算 SKAN 转化值的时间最多为 24 小时。
对于新安装,这不会成为问题。
trackingAuthorizeTimeout
的默认值更改为 30 秒。
Was this page helpful?