iOS SDK 1.35.1미만에는 알려진 이슈가 있습니다. 원활한 SDK 사용을 위해 1.35.1이상을 사용해주세요.
아래와 같은 명령어로 Podfile
파일을 생성해주세요.
cd path/to/project
touch Podfile
Podfile
파일 내용을 아래와 같이 채워주세요.
target '[Project Name]' do
pod 'AirBridge', '1.36.5'
end
Airbridge iOS SDK 1.18.0 이상은 CocoaPods 1.11.0 이상이 필요합니다.
터미널을 여시고 아래와 같은 명령어를 입력해주세요.
cd path/to/project
pod install --repo-update
pod 명령어가 없을 경우, cocoapods 를 설치해주세요.
sudo gem install cocoapods
Swift Package Manager(SPM)를 통해 iOS SDK를 설치할 수 있습니다. SPM을 지원하는 SDK 버전은 1.23.0
이상 입니다.
Xcode에서 File > Add packages로 이동합니다.
Airbridge iOS SDK 추가하기
Apple Swift Package 윈도우가 나타나면 검색창에 Airbridge 패키지의 주소 https://github.com/ab180/airbridge-ios-sdk-deploy를 입력한 후 검색합니다. 이후 원하는 버전을 입력한 후 Add package 버튼을 클릭합니다.
원하는 타겟을 선택한 후 패키지를 추가합니다.
SDK가 바르게 설치되었다면 Package Dependencies
에 AirBridge가 표시됩니다.
AirBridge.framework : 다운로드
Xcode > Project 파일 > General > Frameworks, Libraries, and Embedded Content
의 +
버튼을 눌러주세요.
좌측 하단의 Add Other.. > Add Files..
를 클릭해 다운로드 받은 zip 파일내의 AirBridge.xcframework
폴더를 추가해주세요.
AirBridge.xcframework
Embed 상태를 Embed & Sign 로 변경 해 주세요.
Xcode > Project 파일 > General > Frameworks, Libraries, and Embedded Content
로 이동해주세요.
+
버튼을 눌러주세요.
리스트에서 아래 5개의 [Framework 이름].framework
를 찾아 추가해주세요.
추가한 5개의 [Framework 이름].framework
의 Embed 를 Do not Embed 로 설정해주세요.
Xcode > Project 파일 > Build Phase > Link Binary With Libraries
로 이동해주세요.
5개의[Framework 이름].framework
의 Status 를 Optional 로 설정해주세요.
Framework | 설명 |
---|---|
AdSupport.framework | IDFA 를 수집하는데 사용합니다. |
CoreTelephony.framework | 통신사 정보를 수집하는데 사용합니다. |
StoreKit.framework | SKAdNetwork 정보를 수집하는데 사용합니다. |
AppTrackingTransparency.framework | Tracking 허용 상태정보를 수집하는데 사용합니다. |
AdServices.framework | Apple Search Ads Attribution 정보를 수집하는데 사용합니다. (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 대시보드
> Settings
> Tokens
탭에서 확인하실 수 있습니다.
SDK 를 사용하기 위해서는 앱스토어에 앱을 게시할 때 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' 항목을 체크해 주세요.
앱을 설치하고 실행 했을때 Install 이벤트가 전송되는지 확인해주세요.
SDK 에서 발생한 Event 들은 Airbridge 대시보드
> Raw Data
> App Real-time Logs
에 출력됩니다.
Airbridge 대시보드
> Raw Data
> App Real-time Logs
항목을 클릭해 주세요.
검색어 입력
에 iOS IDFA
를 입력해 주세요. 로그 노출은 최대 5분 가량 지연될 수 있습니다.
SDK 를 초기화하는 코드 상단에 다음 코드를 입력하면 SDK 로그가 출력됩니다.
[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 대시보드
> Tracking Link
> Deep Link
에 아래 2가지 정보가 필요합니다.
iOS URI Scheme
iOS App ID
사용하기 원하는 scheme 을 에어브릿지 대시보드의 iOS URI Scheme
영역에 ://
을 붙여 입력해주세요.
주의하세요
출시 앱 또는 출시 예정 앱과 개발용 앱의 URI 스킴을 다르게 등록해 주세요.
출시 앱 또는 출시 예정 앱과 개발용 앱의 URI 스킴이 동일하면 딥링크가 작동하는 과정에서 의도하지 않은 앱이 실행될 수 있습니다.
https://developer.apple.com/account/resources의 Identifiers
로 이동해 주세요.
Tracking 하고자하는 앱의 Identifier
를 클릭해 주세요.
해당 Identifier
의 App ID Prefix
+ .
+ Bundle ID
를 에어브릿지 대시보드의 iOS App ID
영역에 입력해 주세요.
예) 9JA89QQLNQ.com.apple.wwdc
1. Xcode
> Project 파일
> Info
> URL Types
로 이동해주세요.
2. URL Schemes
에 에어브릿지 대시보드에 입력한 iOS URI Scheme
을 입력해주세요.
주의하세요
URI Scheme 입력 시
://
는 제외하고 입력해주세요.
1. Xcode
> Project 파일
> Signing & Capabilities
로 이동해주세요.
2. + Capability
를 눌러 Associated Domains
를 추가해주세요.
3. Associated Domains
에 applinks:YOUR_APP_NAME.airbridge.io
를 추가해주세요.
4. Associated Domains
에 applinks:YOUR_APP_NAME.abr.ge
를 추가해주세요.
YOUR_APP_NAME
은 대시보드의Settings > Tokens > 앱 이름
에서 확인할 수 있습니다.
Autofill 기능을 사용하는 경우, Troubleshooting > Webcredentials 를 참조해주세요.
iOS 12 및 이전 버전을 지원하는 앱의 경우 일반적으로 AppDelegate
의 application(_:open:options:)
메서드에서 이벤트를 전달합니다.
ios/[프로젝트 이름]/AppDelegate
파일을 열어주세요.
아래 함수의 최상단에서 handleURLSchemeDeeplink
함수를 호출해 App 이 Scheme으로 열렸을 때, SDK에 Deeplink 정보를 전달해주세요.
- (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
}
아래 함수의 최상단에서 handleUserActivity
함수를 호출해 App 이 Universal Link 로 열였을 때, SDK 에 Deeplink 정보를 전달해주세요.
- (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
}
SceneDelegate를 사용하는 프로젝트의 경우 AppDelegate가 아닌 SceneDelegate로 URL이 전달됩니다. SceneDelegate로 URL을 받는 방법은 다음 섹션인 SceneDelegate를 사용하는 경우를 참고해주세요.
iOS 13 및 이후 버전을 지원하는 앱 중 SceneDelegate
를 사용할 경우 다음 메소드로 딥링크가 전달됩니다.
앱이 Not running 상태에서 로드 될 경우: scene(_:willConnectTo:options:)
이외의 경우(ex. 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)
// ...
}
}
SwiftUI를 사용하며 SceneDelegate
를 사용하지 않는 경우 onOpenUrl
로 딥링크를 전달받습니다. SDK 초기화와 마찬가지로 @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)
}
}
}
}
}
SwiftUI를 사용하여 SceneDelegate가 존재하는 프로젝트의 경우 onOpenUrl을 사용할 수 없습니다. 이 경우 위의 SceneDelegate를 사용하는 경우를 참고하세요.
ios/[프로젝트 이름]/AppDelegate
파일을 열어주세요.
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
}
SDK 초기화와 마찬기지로 @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 v1.10.0 ~ v1.10.9
를 사용하는 경우 : Airbridge Deeplink
는 https://YOUR_APP_NAME.airbridge.io/...
형태로 전달됩니다.
Airbridge iOS SDK ~ v1.9.10
를 사용하는 경우 : Airbridge Deeplink
는 https://YOUR_APP_NAME.airbridge.io/...
또는 YOUR_SCHEME://...
형태로 전달됩니다.
딥링크 콜백를 설정하면 디퍼드 딥링크에 대한 정보도 해당 딥링크 콜백으로 전달됩니다. 디퍼드 딥링크 콜백 설정은 딥링크 콜백 설정을 참고해 주세요.
디퍼드 딥링크 콜백은 앱을 설치한 이후에 단 1번만 제공됩니다.
Airbridge 대시보드의 iOS URI Scheme
에 입력한 YOUR_SCHEME://...
형태의 딥링크를 클릭하였을 때, 앱이 열리고 Deeplink 이벤트가 전송되는지 확인해주세요.
딥링크를 클릭해주세요.
Airbridge 대시보드
> Raw Data
> App Real-time Logs
에서 Deeplink 이벤트가 존재하는지 확인해주세요.
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 | - |
사용자 Email | 자동으로 SHA256 으로 Hash 됨 (옵션으로 해제가능) | |
phone | 사용자 전화번호 | 자동으로 SHA256 으로 Hash 됨 (옵션으로 해제가능) |
alias | 사용자의 또 다른 ID | - 최대 10개 입니다. |
MTA(Multi-Touch Attribution) 분석의 정확도 향상, 내부 데이터 분석, 서드파티(3rd Party) 솔루션 연동 등의 목적으로 사용자의 추가 속성 데이터를 설정할 수 있습니다.
// 입력된 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)
이름 | 설명 | 제한 |
---|---|---|
attributes | 사용자 속성 | - 최대 100개 입니다. |
사용자 설정을 완료한 후, SDK 를 통해 Event 를 전송하고, 해당 Event 에 설정한 사용자 정보가 있는지 확인해주세요.
사용자 설정을 해주세요.
SDK 를 통해 Event 를 전송해주세요.
Airbridge 대시보드
> Raw Data
> App Real-time Logs
에서 전송한 Event 를 클릭하여 JSON 속 user 부분에 설정한 사용자 정보가 있는지 확인해주세요.
SDK에 디바이스 식별자 정보를 설정해 이후 수집되는 모든 이벤트에 디바이스 식별정보를 포함시킬 수 있습니다. 디바이스 식별자가 설정되면 별도로 삭제하지 않을 경우 앱 종료 여부에 관계없이 계속 유지됩니다.
[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) | 전달한 Key와 Value 쌍을 디바이스 식별자에 추가합니다. |
removeDeviceAlias(withKey: String) | 전달한 Key에 해당하는 디바이스 식별자를 삭제합니다. 만약 해당하는 식별자가 없을 경우 아무런 동작을 하지 않습니다. |
clearDeviceAlias() | 모든 디바이스 식별자를 삭제합니다. |
사용자의 중요한 행동들이 발생할 때, 인앱 이벤트를 전송해 유입 경로별 성과를 측정할 수 있습니다.
모든 이벤트의 파라미터는 선택적으로 추가할 수 있습니다. 그러나 이벤트에 대한 많은 정보는 정확한 통계 제공에 도움이 됨으로 추가하는 것을 권장합니다.
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 | 이벤트 이름 (required) |
setAction | 이벤트 하위 분류 1 |
setLabel | 이벤트 하위 분류 2 |
setValue | 이벤트 커스텀 값 |
setCustoms | 이벤트 커스텀 정보 |
setSemantics | 이벤트 시맨틱 정보 (Map) |
#import <AirBridge/ABUser.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
ABUser* user = [[ABUser alloc] init];
user.ID = @"testID";
user.email = @"testID@ab180.co";
user.phone = @"000-0000-0000";
user.alias = @{
@"key": @"value",
};
user.attributes = @{
@"key": @"value",
};
[AirBridge.state setUser:user];
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.signUp];
[event send];
let user = ABUser()
user.id = "testID"
user.email = "testID@ab180.co"
user.phone = "000-0000-0000"
user.attributes = [
"key": "value" as NSObject,
]
user.alias = [
"key": "value",
]
AirBridge.state().setUser(user)
let event = ABInAppEvent()
event?.setCategory(ABCategory.signUp)
event?.send()
#import <AirBridge/ABUser.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
ABUser* user = [[ABUser alloc] init];
user.ID = @"testID";
user.email = @"testID@ab180.co";
user.phone = @"000-0000-0000";
user.alias = @{
@"key": @"value",
};
user.attributes = @{
@"key": @"value",
};
[AirBridge.state setUser:user];
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.signIn];
[event send];
let user = ABUser()
user.id = "testID"
user.email = "testID@ab180.co"
user.phone = "000-0000-0000"
user.attributes = [
"key": "value" as NSObject,
]
user.alias = [
"key": "value",
]
AirBridge.state().setUser(user)
let event = ABInAppEvent()
event?.setCategory(ABCategory.signIn)
event?.send()
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.signOut];
[AirBridge.state setUser:[[ABUser alloc] init]];
let event = ABInAppEvent()
event?.setCategory(ABCategory.signOut)
event?.send()
AirBridge.state().setUser(ABUser())
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.viewHome];
[event send];
let event = ABInAppEvent()
event?.setCategory(ABCategory.viewHome)
event?.send()
#import <AirBridge/ABProduct.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
#import <AirBridge/ABSemanticsKey.h>
ABProduct* product1 = [[ABProduct alloc] init];
product1.idx = @"idx1";
product1.name = @"name1";
product1.price = @100;
product1.currency = @"USD";
product1.orderPosition = @1;
product1.quantity = @1;
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.viewProductDetail];
[event setSemantics:@{
ABSemanticsKey.products: @[product1.toDictionary],
}];
[event send];
let product1 = ABProduct()
product1.idx = "idx1"
product1.name = "name1"
product1.price = 100
product1.currency = "USD"
product1.orderPosition = 1
product1.quantity = 1
let event = ABInAppEvent()
event?.setCategory(ABCategory.viewProductDetail)
event?.setSemantics([
ABSemanticsKey.products: [
product1.toDictionary(),
],
])
event?.send()
#import <AirBridge/ABProduct.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
#import <AirBridge/ABSemanticsKey.h>
ABProduct* product1 = [[ABProduct alloc] init];
product1.idx = @"idx1";
product1.name = @"name1";
product1.price = @100;
product1.currency = @"USD";
product1.orderPosition = @1;
product1.quantity = @1;
ABProduct* product2 = [[ABProduct alloc] init];
product2.idx = @"idx2";
product2.name = @"name2";
product2.price = @200;
product2.currency = @"USD";
product2.orderPosition = @2;
product2.quantity = @2;
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.viewProductList];
[event setSemantics:@{
ABSemanticsKey.products: @[
product1.toDictionary,
product2.toDictionary,
],
ABSemanticsKey.productListID: @"listID",
}];
[event send];
let product1 = ABProduct()
product1.idx = "idx1"
product1.name = "name1"
product1.price = 100
product1.currency = "USD"
product1.orderPosition = 1
product1.quantity = 1
let product2 = ABProduct()
product2.idx = "idx2"
product2.name = "name2"
product2.price = 200
product2.currency = "USD"
product2.orderPosition = 2
product2.quantity = 2
let event = ABInAppEvent()
event?.setCategory(ABCategory.viewProductList)
event?.setSemantics([
ABSemanticsKey.products: [
product1.toDictionary(),
product2.toDictionary(),
],
ABSemanticsKey.productListID: "productListID",
])
event?.send()
#import <AirBridge/ABProduct.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
#import <AirBridge/ABSemanticsKey.h>
ABProduct* product1 = [[ABProduct alloc] init];
product1.idx = @"idx1";
product1.name = @"name1";
product1.price = @100;
product1.currency = @"USD";
product1.orderPosition = @1;
product1.quantity = @1;
ABProduct* product2 = [[ABProduct alloc] init];
product2.idx = @"idx2";
product2.name = @"name2";
product2.price = @200;
product2.currency = @"USD";
product2.orderPosition = @2;
product2.quantity = @2;
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.viewSearchResult];
[event setSemantics:@{
ABSemanticsKey.products: @[
product1.toDictionary,
product2.toDictionary,
],
ABSemanticsKey.query: @"query",
}];
[event send];
let product1 = ABProduct()
product1.idx = "idx1"
product1.name = "name1"
product1.price = 100
product1.currency = "USD"
product1.orderPosition = 1
product1.quantity = 1
let product2 = ABProduct()
product2.idx = "idx2"
product2.name = "name2"
product2.price = 200
product2.currency = "USD"
product2.orderPosition = 2
product2.quantity = 2
let event = ABInAppEvent()
event?.setCategory(ABCategory.viewSearchResult)
event?.setSemantics([
ABSemanticsKey.products: [
product1.toDictionary(),
product2.toDictionary(),
],
ABSemanticsKey.query: "query",
])
event?.send()
#import <AirBridge/ABProduct.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
#import <AirBridge/ABSemanticsKey.h>
ABProduct* product1 = [[ABProduct alloc] init];
product1.idx = @"idx1";
product1.name = @"name1";
product1.price = @100;
product1.currency = @"USD";
product1.orderPosition = @1;
product1.quantity = @1;
ABProduct* product2 = [[ABProduct alloc] init];
product2.idx = @"idx2";
product2.name = @"name2";
product2.price = @200;
product2.currency = @"USD";
product2.orderPosition = @2;
product2.quantity = @2;
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.addToCart];
[event setSemantics:@{
ABSemanticsKey.products: @[
product1.toDictionary,
product2.toDictionary,
],
ABSemanticsKey.cartID: @"cartID",
ABSemanticsKey.currency: @"currency"
}];
[event setValue:@300];
[event send];
let product1 = ABProduct()
product1.idx = "idx1"
product1.name = "name1"
product1.price = 100
product1.currency = "USD"
product1.orderPosition = 1
product1.quantity = 1;
let product2 = ABProduct()
product2.idx = "idx2"
product2.name = "name2"
product2.price = 200
product2.currency = "USD"
product2.orderPosition = 2
product2.quantity = 2;
let event = ABInAppEvent()
event?.setCategory(ABCategory.addToCart)
event?.setSemantics([
ABSemanticsKey.products: [
product1.toDictionary(),
product2.toDictionary(),
],
ABSemanticsKey.cartID: "cartID",
ABSemanticsKey.currency: "KRW",
])
event.setValue(300)
event?.send()
#import <AirBridge/ABProduct.h>
#import <AirBridge/ABInAppEvent.h>
#import <AirBridge/ABCategory.h>
#import <AirBridge/ABSemanticsKey.h>
ABProduct* product1 = [[ABProduct alloc] init];
product1.idx = @"coke_zero";
product1.name = @"Coke Zero";
product1.price = @100;
product1.currency = @"USD";
product1.orderPosition = @1;
product1.quantity = @1;
ABProduct* product2 = [[ABProduct alloc] init];
product2.idx = @"burger_cheese_double";
product2.name = @"Double Cheeseburger";
product2.price = @200;
product2.currency = @"USD";
product2.orderPosition = @2;
product2.quantity = @2;
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:ABCategory.purchase];
[event setSemantics:@{
ABSemanticsKey.products: @[
product1.toDictionary,
product2.toDictionary,
],
ABSemanticsKey.transcationID: @"transcationID",
ABSemanticsKey.currency: @"currency",
ABSemanticsKey.inAppPurchased: @YES
}];
[event setValue:@300];
[event send];
let product1 = ABProduct()
product1.idx = "coke_zero"
product1.name = "Coke Zero"
product1.price = 100
product1.currency = "USD"
product1.orderPosition = 1
product1.quantity = 1
let product2 = ABProduct()
product2.idx = "burger_cheese_double"
product2.name = "Double Cheeseburger"
product2.price = 200
product2.currency = "USD"
product2.orderPosition = 2
product2.quantity = 2
let event = ABInAppEvent()
event?.setCategory(ABCategory.purchase)
event?.setSemantics([
ABSemanticsKey.products: [
product1.toDictionary(),
product2.toDictionary(),
],
ABSemanticsKey.transactionID: "transactionID",
ABSemanticsKey.currency: "KRW",
ABSemanticsKey.inAppPurchased: true
])
event?.setValue(300)
event?.send()
SDK 를 통해 Event 를 전송하고, 에어브릿지 대시보드에 해당 Event 가 존재하는지 확인해주세요.
SDK 를 통해 Event 를 전송해주세요.
Airbridge 대시보드 > Raw Data
> App Real-time Logs
에서 전송한 Event 가 존재하는지 확인해주세요.
개인정보보호법 등으로 인해 IDFA 수집이 불가능 한 경우 기존 SDK 대신 IDFA 수집 기능이 제거된 restricted SDK 를 사용 할 수 있습니다. restricted SDK 는 v1.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 Signature 를 설정하는 것으로 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 Signature를 설정하기 위해서는 SDK Signature 보안 정보가 필요합니다. SDK Signature 보안 정보를 생성하기 위한 자세한 내용은 에어브릿지 가이드를 참고해 주세요.
유저의 정보 중 email, phone 정보는 자동으로 SHA256 으로 Hash 되어 전송합니다.
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
함수를 호출해 세션 타임아웃을 설정할 수 있습니다.
세션 타임아웃은 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
함수가 호출 될 때 까지 이벤트를 전송하지 않습니다.
따라서, 앱이 꺼져있는 상태에서 라이프사이클 이벤트(Deeplink Open 등) 발생 시, 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()
알립니다
필수 설정 기능이 아닙니다. 필요한 기능인지 확인한 후에 설정해 주세요.
옵트아웃(Opt-Out)은 유저가 거부하기 전에 유저 정보를 사용하는 정책입니다.
setAutoStartTrackingEnabled
설정을 true로 설정한 후에 이벤트를 수집할 수 없는 시점에 stopTracking
함수를 호출합니다. stopTracking
함수가 호출된 시점부터 이벤트를 수집하지 않습니다.
#import <AirBridge/AirBridge.h>
AirBridge.autoStartTrackingEnabled = YES;
[AirBridge getInstance:@"YOUR_APP_SDK_TOKEN" appName:@"YOUR_APP_NAME" withLaunchOptions:launchOptions];
[AirBridge stopTracking];
import Airbridge
AirBridge.setAutoStartTrackingEnabled(true)
AirBridge.getInstance("YOUR_APP_SDK_TOKEN", appName: "YOUR_APP_NAME", withLaunchOptions: launchOptions)
AirBridge.stopTracking()
SDK 는 딥링크로 앱이 열렸을 때, 언제나 딥링크 이벤트를 전송합니다.
SDK 를 초기화하는 코드 상단에 setIsTrackAirbridgeDeeplinkOnly
함수를 호출해 true 로 설정하면, Airbridge 를 통한 딥링크
로 앱이 열린 경우에만 딥링크 이벤트를 전송할 수 있습니다.
// 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)
아래 설정을 통해 Facebook 의 Deferred App Link 를 SDK 에서 수집할 수 있습니다.
아래 페이스북 개발자 가이드를 참고하여 Facebook SDK 를 설치해주세요.
ios/[프로젝트 이름]/AppDelegate
파일을 열어주세요.
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)
앱 삭제 추적 설정은 해당 페이지를 참조해 주세요.
푸시 알림이 클릭되었을 때, handleNotificationDeeplink
함수를 호출해 푸시 알림 페이로드의 딥링크를 SDK 에 전달해주세요.
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
if (UIApplication.sharedApplication.applicationState == UIApplicationStateInactive || UIApplication.sharedApplication.applicationState == UIApplicationStateBackground) {
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 || UIApplication.shared.applicationState == .background {
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)
}
}
앱 추적 투명성(App Tracking Transparency, ATT) 정책에 따라 iOS 버전 14.5 이상에서 IDFA를 수집하기 위해서는 반드시 AppTrackingTransparency.framework를 사용한 팝업창으로 개인정보 사용에 관한 유저 동의를 받아야 합니다. 해당 프레임워크를 사용한 팝업창에서 개인정보 사용에 동의한 유저의 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)
}
}
AppTrackingTransparency.framework 를 사용해 추적 허용 선택창
을 표시하는 경우, 추적 허용
을 선택하더라도 선택하기 이전에 설치 이벤트가 전송되기 때문에 설치 이벤트에서 IDFA 수집이 불가능합니다.
SDK 초기화 코드 이전에 trackingAuthorizeTimeout
에 timeout
을 설정하면, 설치 이벤트를 전송하기 전에 timeout
만큼 추적 허용 선택창
이 선택될 때 까지 기다립니다.
trackingAuthorizeTimeout
은 millisecond 단위입니다.
trackingAuthorizeTimeout
만큼 설치 이벤트가 늦게 전송될 수 있습니다.
trackingAuthorizeTimeout
App 재시작 마다 초기화됩니다.
ATT 상태가 선택되거나, timeout 이 발생했을 때 deferred deeplink 가 callback 에 전달됩니다.
App 재시작마다 timeout 을 초기화하지 않기 위해서는 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)
주의하세요
위 코드 중
trackingAuthorizeTimeout
값은 SDK 버전이 1.32.1+ 이상인 iOS SDK의 기본값(30초)입니다. 실제로 활용할 때는 반드시 앱의 UX(사용자 경험)와 ATT 프롬프트 설정에 맞게 값을 바꿔야 합니다.
Airbridge SDK 는 이벤트를 전송할 수 없는 환경인 경우에 대비해서 이벤트를 스토리지에 저장하고 재시도하는 기능을 가지고 있습니다. 이 기능을 통해 Airbridge 가 이벤트를 저장하는데 사용하는 스토리지를 제한할 수 있습니다. 설정된 제한은 다음 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 는 이벤트를 전송하는 최소 주기를 설정할 수 있습니다. 이벤트를 1회 전송하는데 성공하면 설정한 주기 만큼은 이벤트가 전송되지 않게 됩니다. 기본 이벤트 전송 주기는 0 millisecond 입니다.
// 이벤트 전송 주기 (Millisecond 단위)
[AirBridge.setting setEventTransmitInterval:newValue]
// 이벤트 전송 주기 (Millisecond 단위)
AirBridge.setting().setEventTransmitInterval(newValue)
Airbridge 초기화 시 내부 저장소에 저장된 모든 이벤트를 삭제하는 기능입니다. Airbridge는 이벤트 전송 시 손실을 최소화하기 위해 전송되지 않은 이벤트를 내부 저장소에 저장합니다. 하지만 이 기능이 활성화되어있을 경우, Airbridge가 초기화될 때 저장소에 있는 이벤트를 모두 삭제합니다.
// 활성화
Airbridge.setResetEventBufferEnabled(true)
// 비활성화
Airbridge.setResetEventBufferEnabled(false)
주의하세요
해당 함수는 Airbridge이 트래킹을 시작하기 전에 실행되어야 합니다. 즉,
autoStartTracking
이true
로 설정되어 있을 경우getInstance
이전,false
로 설정되어 있을 경우startTracking
이전에 실행되어야 합니다. 그렇지 않을 경우 해당 기능은 동작하지 않습니다.
주의하세요
에어브릿지의 iOS SDK 1.24.0 이상에서 인앱에서 트래킹 링크 활용하기를 설정하면 앱에서 트래킹 링크를 사용할 때마다 딥링크 페이지뷰(Deeplink Pageview)가 타겟 이벤트로 집계됩니다. 딥링크 실행(Deeplink Open) 직후에 딥링크 페이지뷰가 빈번하게 발생하면 딥링크 실행 성과에 영향을 줄 수 있습니다.
딥링크 페이지뷰의 어트리뷰션 윈도우 기본 설정은 3일입니다. 딥링크 페이지뷰의 어트리뷰션 윈도우 변경을 원하는 고객사는 에어브릿지 CSM에게 문의해 주세요.
앱에서 트래킹 링크를 사용할 수 있습니다. 단, 커스텀 숏 ID를 사용하는 트래킹 링크는 앱에서 사용할 수 없습니다. 해당 기능을 사용하면 외부 브라우저를 거치지 않고 앱에서 같은 앱의 다른 페이지로 이동할 수 있습니다.
Airbridge.placement().click("https://abr.ge/~~~")
Airbridge.placement().impression("https://abr.ge/~~~")
해당 트래킹 링크가 클릭되었을 때 호출합니다. 그 후 트래킹 링크의 click 통계를 추가하고 설정된 App, Web 또는 Fallback으로 이동합니다.
해당 트래킹 링크가 UI에 표시 되었을 때 호출합니다. 그 후 트래킹 링크의 impression 통계를 1개 추가합니다.
에어브릿지 iOS SDk에서 어트리뷰션 결과를 확인하기 위해서는 attributionCallback
에 콜백 클로저를 전달해야 합니다.
Attribution Result 콜백은 앱을 설치한 이후에 단 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) |
기여 결과가 없는 경우 attributedChannel
항목에 대해 unattributed
데이터가 전달됩니다.
{
"attributedChannel": "unattributed"
}
Attribution 값 사용에 대한 가이드라인:
기여 결과가 존재하는 경우
Attribution 값은 SDK 초기화 후 대체로 40초 내외에 콜백으로 전달됩니다.
앱이 종료되어 이전에 Attribution 값을 전달받지 못한 경우, 다음 앱 실행 시 SDK 초기화 후 40초 내외에 Attribution 값이 전달됩니다.
드물게 최대 5분까지 전달이 지연될 수 있습니다.
기여 결과가 존재하지 않는 경우 SDK를 초기화한 이후, 최소 3시간이 경과한 후 앱 재실행 시 Attribution 값이 전달됩니다.
실시간 처리가 필요한 부분에는 콜백으로 전달되는 Attribution 값을 활용하는 것은 권장하지 않습니다.
Airbridge 생명 주기 이벤트 중 앱이 Background로 이동하고 세션 안에 발생하는 생명 주기 이벤트는 기본적으로 수집되지 않습니다. 이 옵션을 사용하면 이 이벤트들을 수집할 수 있습니다.
[AirBridge.setting setTrackInSessionLifeCycleEventEnabled:YES];
AirBridge.setting().setTrackInSessionLifeCycleEventEnabled(true)
Airbridge의 전체 동작을 비활성화 할 수 있는 기능입니다. 앱 라이프 사이클 추적, 이벤트 전송 등 Airbridge의 모든 기능이 비활성화 됩니다.
// 활성화
Airbridge.setSDKEnabled(true)
// 비활성화
Airbridge.setSDKEnabled(false)
주의하세요
해당 함수는 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 를 활용하시는 경우, SKAdNetwork 의 전환값 측정이 제대로 작동하지 않게 되기 때문에 SKAdNetwork 기능을 사용하지 않으셔야 합니다.
디지털 시장법(DMA)를 준수하기 위해서는 유저 응답 정보(User Consent)를 에어브릿지에 전달해야 합니다. DMA와 적용 대상 등에 대한 자세한 내용은 에어브릿지 가이드를 참고해 주세요.
EEA(유럽 경제 지역)이라면 유저의 유럽 경제 지역 여부와 유저 응답 정보를 항상 에어브릿지에 전달해야 합니다.
1. 앱을 실행한 유저의 지역을 확인합니다. 유저가 앱을 실행한 지역이 EEA(eea=1)
라면 기존에 수집한 유저 응답 정보가 있는지 확인합니다. 수집한 유저 응답 정보가 있다면 3번을 진행합니다.
유저가 앱을 실행한 지역이 EEA가 아니라면 유저 응답 정보를 수집하지 않아도 됩니다.
알립니다
에어브릿지는 유저 응답 정보 저장과 프롬프트 구현 방식 등에 관해 도움을 드릴 수 없습니다. 법률 자문사와 함께 검토해 주세요.
2. 수집한 유저 응답 정보가 없다면 프롬프트 등으로 유저 응답 정보를 수집합니다. 해당 단계에서 수집해야 하는 정보는 adPersonalization
, adUserData
입니다.
주의하세요
2024년 3월 6일부터 EEA 지역에 있는 기존 유저와 신규 유저에 대한 유저 응답 정보를 최소 1번이라도 수집해야 합니다.
에어브릿지에 전달해야 하는 유저 응답 정보는 아래와 같습니다. eea
는 유저가 응답한 정보 또는 에어브릿지가 자동으로 수집하는 정보가 아닙니다. 유저가 있는 지역에 따라 결정한 eea
값을 전달해 주세요.
에어브릿지 필드 이름 |
구글 필드 이름 |
설명 |
---|---|---|
<string> |
| 디지털 시장법(DMA)를 준수해야 하는 지역에 대한 정보. 유저가 응답한 정보 또는 에어브릿지가 자동으로 수집하는 정보가 아닙니다. 유저가 있는 지역에 따라 알맞게 전송해 주세요.
- - |
<string> |
| 개인 맞춤형 광고(Personalized Ads) 제공을 위한 정보 수집에 대한 동의 설정. - - |
<string> |
| 광고에 사용하는 유저 데이터를 구글에 전송하는 것에 대한 동의 설정. - - |
3. 에어브릿지 SDK를 초기화하고 유저 정보를 수집하기 전에 유저 응답 정보를 에어브릿지에 전달합니다.
주의하세요
아래를 주의해 주세요.
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];
}
WebView 의 웹사이트에 설치된 Web SDK 가 전송하는 Event 를 iOS SDK가 대신 전송할 수 있습니다.
아래와 같이 WebView 의 configuration 의 controller 에 airbridge web interface 를 주입해주세요.
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
은 대시보드의 Settings > Tokens > 웹 SDK 토큰
에서 확인할 수 있습니다.
App 에서 Autofill 기능을 사용해 비밀번호를 저장하는 경우 webcredentials:...
설정이 되어 있지 않으면 비밀번호가 applinks:YOUR_APP_NAME.airbridge.io
또는 applinks:YOUR_APP_NAME.abr.ge
의 도메인에 저장됩니다.
비밀번호가 저장되는 도메인을 변경하고 싶다면, example.com
을 설정할 도메인
으로 변경해서 아래와 같이 설정해주세요.
https://example.com/.well-known/apple-app-site-association
주소에서 아래 내용을 호스팅 합니다.
{
"webcredentials": {
"apps": ["TEAM_ID.APP_BUNDLE_ID"]
}
}
예) 9JA89QQLNQ.com.apple.wwdc
Xcode > Project 파일 > Signing & Capabilities > Associated Domains 로 이동해주세요.
+
버튼을 눌러 webcredentials:example.com
을 추가해주세요.
Airbridge iOS SDK 는 1.28.0 버전 부터 Bitcode 를 지원하지 않습니다. (Xcode 14 부터 Bitcode 가 deprecate 되었습니다.)
하지만 App 프로젝트에서 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
Xcode 에서 ENABLE_BITCODE 설정을 NO 로 설정해주시면 됩니다.
Apple Appstore 에서는 Bitcode 를 Deprecate 하여 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 이상을 필요로 합니다. 그런데 Swift Package Manager 에는 Link 될 Framework 의 Minimum OS Version
이 Target 의 Minimum OS Version
보다 높으면 자동으로 Optional
로 Link 하는 기능이 있지만, Swift Package Manager 를 사용하지 않고 Metadata 만 가져와서 Swift Package Manager 의 동작을 대신하는 Tuist fetch 에는 무조건 Required
로 Link 해서 이 이슈가 발생합니다. (문제가 되는 Tuist 코드)
이 경우, 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년 9월 4일 이후에 생성된 에어브릿지 앱의 경우, 딥링크 콜백에서 제공하는 딥링크 URL 이 에어브릿지 대시보드에 입력된 내용을 2번 디코딩하여 제공하는 문제가 1.34.0 ~ 1.35.1 에 있었던 것이 해결되었습니다.
2023년 9월 4일 이후에 생성된 에어브릿지 앱의 경우, 딥링크 콜백에서 제공하는 딥링크 URL 에 더이상 airbridge_referrer 가 추가되지 않게 됩니다.
1.33.0 미만 버전을 사용하시는 유저가 업데이트하시는 경우, 마지막으로 계산된 SKAdNetwork Conversion Value 로 확정되고, 추가적으로 계산하지 않습니다.
1.33.0 미만 버전에서는 SKAdNetwork Conversion Value 를 최대 24시간 동안만 계산합니다.
새로 설치하시는 유저에 대해서는 문제되지 않습니다.
trackingAuthorizeTimeout 의 기본값이 30초로 변경됩니다.
도움이 되었나요?