에어브릿지 iOS SDK를 업데이트하는 과정에 필요한 내용을 확인할 수 있습니다. 현재 버전 이후부터 업데이트 이후 버전까지의 내용을 모두 확인하는 것을 권장합니다.
에어브릿지 iOS SDK를 v4.0으로 업데이트하면 확인해 주세요.
iOS SDK 이름이 AirBridge에서 Airbridge로 변경되었습니다. AirBridge 클래스가 Airbridge 클래스로 변경되었습니다. 함수와 옵션의 이름이 변경되었습니다.
AirBridge | AirbridgeOptionBuilder | 변경점 |
---|---|---|
- | AirbridgeOptionBuilder(name: String, token: String) | 옵션을 Builder를 통해 설정하실 수 있도록 변경되었습니다. |
- | build() | SDK 초기화 이후 옵션을 수정하실 수 없도록 변경되었습니다. |
setLogLevel(ABLogLevel) | setLogLevel(AirbridgeLogLevel) | 타입 이름이 변경되었습니다. |
setPaginateLogEnabled(Bool) | setPaginateLogEnabled(Bool) | - |
state().setSDKDevelopmentPlatform(String) | setSDKDevelopmentPlatform(String) | 이름이 변경되었습니다. |
- | setAppGroup(String) | 새로운 기능이 추가되었습니다. |
setSDKEnabled(Bool) | setSDKEnabled(Bool) | - |
- | setTrackingLinkCustomDomains([String]) | Info.plist를 통해 설정하던 것이 옵션으로 변경되었습니다. |
setIsFacebookDeferredAppLinkEnabled(Bool) | setTrackMetaDeferredAppLinkEnabled(Bool) | 이름이 변경되었습니다. |
deeplink().setDeeplinkCallback((String) -> Void) | - | handleDeeplink 함수로 역할이 이전되었습니다. |
deeplink().setDeferredDeeplinkCallback((String) -> Void) | - | handleDeferredDeeplink 함수로 역할이 이전되었습니다. |
deeplink().setHandleTrackingLinkTimeout: UInt | - | 기능이 제거되었습니다. (기본값인 3초로 고정됩니다.) |
setAutoStartTrackingEnabled(Bool) | setAutoStartTrackingEnabled(Bool) | - |
- | setAutoDetermineTrackingAuthorizationEnabled(Bool) | 새로운 기능이 추가되었습니다. |
setting().trackingAuthorizeTimeout: UInt | setAutoDetermineTrackingAuthorizationTimeout(second: Double) | 이름이 변경되었습니다. 그리고 단위가 밀리초에서 초로 변경되었습니다. 또 최대 1시간 제한이 추가되었습니다. |
setting().isRestartTrackingAuthorizeTimeout: Bool | - | 기능이 제거되었습니다. (기본값인 true로 고정됩니다.) |
setIsUserInfoHashed(Bool) | setHashUserInformationEnabled(Bool) | 이름이 변경되었습니다. |
setSessionTimeout(Int) | setSessionTimeout(second: Double) | 단위가 밀리초에서 초로 변경되었습니다. 그리고 최대 7일 제한이 추가되었습니다. |
setting().setTrackInSessionLifeCycleEventEnabled(Bool) | setTrackInSessionLifecycleEventEnabled(Bool) | 이름이 변경되었습니다. |
setIsTrackAirbridgeDeeplinkOnly(Bool) | setTrackAirbridgeDeeplinkOnlyEnabled(Bool) | 이름이 변경되었습니다. |
setSDKSignature(id: String, secret: String) | setSDKSignature(id: String, secret: String) | - |
resetEventBufferEnabled(Bool) | setClearEventBufferOnInitializeEnabled(Bool) | 이름이 변경되었습니다. |
setting().isResetEventBufferEnabled: Bool | setClearEventBufferOnInitializeEnabled(Bool) | 이름이 변경되었습니다. |
- | setPauseEventTransmitOnBackgroundEnabled(Bool) | 새로운 기능이 추가되었습니다. |
setting().setEventMaximumBufferCount(UInt) | setEventBufferCountLimit(Int) | 이름이 변경되었습니다. |
setting().setEventMaximumBufferSize(UInt) | setEventBufferSizeLimit(gibibyte: Double) | 이름이 변경되었습니다. 그리고 단위가 byte에서 gibibyte로 변경되었습니다. |
setting().setEventTransmitInterval(UInt) | setEventTransmitInterval(second: Double) | 이름이 변경되었습니다. 그리고 단위가 밀리초에서 초로 변경되었습니다. 또 최대 1일 제한이 추가되었습니다. |
setting().attributionCallback: ([String: String]) -> Void | setOnAttributionReceived(([String: String]) -> Void) | 이름이 변경되었습니다. |
AirBridge | Airbridge | 변경점 |
---|---|---|
getInstance(String, appName: String) | initializeSDK(option: AirbridgeOption) | 이름이 변경되었습니다. |
isSDKEnabled: Bool | isSDKEnabled: Bool | - |
enableSDK() | enableSDK() | - |
disableSDK() | disableSDK() | SDK 구성요소에 접근을 제한하던 구현방식이 구성요소를 메모리에서 제거하도록 변경되었습니다. |
startTracking() | startTracking() | - |
deeplink().handleURLSchemeDeeplink(URL) | trackDeeplink(url: URL) | 이름이 변경되었습니다. |
deeplink().handleUserActivity(NSUserActivity) | trackDeeplink(userActivity: NSUserActivity) | 이름이 변경되었습니다. |
- | handleDeeplink(url: URL, onSuccess: (URL) -> Void, onFailure: (Error) -> Void) -> Bool | setDeeplinkCallback 옵션이 이동되었습니다. |
- | handleDeeplink(userActivity: NSUserActivity, onSuccess: (URL) -> Void, onFailure: (Error) -> Void) -> Bool | setDeeplinkCallback 옵션이 이동되었습니다. |
- | handleDeferredDeeplink(url: URL, onSuccess: (URL) -> Void, onFailure: (Error) -> Void) -> Bool | setDeferredDeeplinkCallback 옵션이 이동되었습니다. |
- | trackEvent(category: String, semanticAttributes: [String: Any], customAttributes: [String: Any]) | 이벤트 전송방식이 변경되었습니다. |
placement().click(URL, completion: (Error?) -> Void) | click(trackingLink: URL, onSuccess: () -> Void, onFailure: (Error) -> Void) -> Bool | 이름이 변경되었습니다. |
placement().impression(URL, completion: (Error?) -> Void) | impression(trackingLink: URL, onSuccess: () -> Void, onFailure: (Error) -> Void) -> Bool | 이름이 변경되었습니다. |
webInterface().inject(to: WKUserContentController, withWebToken: String) | setWebInterface(controller: WKUserContentController, webToken: String) | 이름이 변경되었습니다. 그리고 DeviceAlias 연동기능이 추가되었습니다. |
deviceUUID: String | fetchDeviceUUID(onSuccess: (String) -> Void, onFailure: (Error) -> Void) -> Bool | 이름이 변경되었습니다. 함수가 비동기적으로 동작하도록 수정되었습니다. |
fetchAirbridgeGeneratedUUID((String) -> Void) -> Bool | fetchAirbridgeGeneratedUUID(onSuccess: (String) -> Void, onFailure: (Error) -> Void) -> Bool | 이름이 변경되었습니다. |
- | isUninstallTrackingNotification([String: Any]) -> Bool | 새로운 기능이 추가되었습니다. |
state().setUserID(String) | setUserID(String) | 이름이 변경되었습니다. |
- | clearUserID() | 새로운 기능이 추가되었습니다. |
state().setUserEmail(String) | setUserEmail(String) | 이름이 변경되었습니다. |
- | clearUserEmail() | 새로운 기능이 추가되었습니다. |
state().setUserPhone(String) | setUserPhone(String) | 이름이 변경되었습니다. |
- | clearUserPhone() | 새로운 기능이 추가되었습니다. |
addUserAttribute(key: String, value: Any) | setUserAttribute(key: String, value: Any) | 이름이 변경되었습니다. |
removeUserAttribute(String) | removeUserAttribute(key: String) | 이름이 변경되었습니다. |
clearUserAttributes() | clearUserAttributes() | - |
addUserAlias(key: String, value: String) | setUserAlias(key: String, value: String) | 이름이 변경되었습니다. |
removeUserAlias(String) | removeUserAlias(key: String) | 이름이 변경되었습니다. |
clearUserAlias() | clearUserAlias() | - |
- | clearUser() | 새로운 기능이 추가되었습니다. |
addDeviceAlias(key: String, value: String) | setDeviceAlias(key: String, value: String) | 이름이 변경되었습니다. |
setDeviceAlias(key: String, value: String) | setDeviceAlias(key: String, value: String) | - |
removeDeviceAlias(key: String) | removeDeviceAlias(key: String) | - |
clearDeviceAlias() | clearDeviceAlias() | - |
registerPushToken(Data) | registerPushToken(Data) | - |
ABInAppEvent | Airbridge | 변경점 |
---|---|---|
setCategory(String) | trackEvent(category: String, semanticAttributes: [String: Any], customAttributes: [String: Any]) | AirbridgeCategory 또는 String을 category 파라미터에 입력해주세요. |
setAction(String) | trackEvent(category: String, semanticAttributes: [String: Any], customAttributes: [String: Any]) | AirbridgeAttribute.ACTION를 키로 사용해서 semanticAttributes 파라미터에 입력해주세요. |
setLabel(String) | trackEvent(category: String, semanticAttributes: [String: Any], customAttributes: [String: Any]) | AirbridgeAttribute.LABEL를 키로 사용해서 semanticAttributes 파라미터에 입력해주세요. |
setValue(NSNumber) | trackEvent(category: String, semanticAttributes: [String: Any], customAttributes: [String: Any]) | AirbridgeAttribute.VALUE를 키로 사용해서 semanticAttributes 파라미터에 입력해주세요. |
setSemantics([String: Any]) | trackEvent(category: String, semanticAttributes: [String: Any], customAttributes: [String: Any]) | ABSemanticsKey를 사용한 키는 AirbridgeAttribute를 사용하고 String을 사용한 키는 그대로 semanticAttributes 파라미터에 입력해주세요. 그리고 products의 value에는 ABProductKey를 사용한 키는 AirbridgeAttribute를 사용하고 String을 사용한 키는 그대로 입력해주세요. |
setCustoms([String: Any]) | trackEvent(category: String, semanticAttributes: [String: Any], customAttributes: [String: Any]) | 키, 밸류를 그대로 customAttributes에 입력해주세요. |
ABCategory | AirbridgeCategory | 변경점 |
---|---|---|
signUp | SIGN_UP | 이름이 변경되었습니다. |
signIn | SIGN_IN | 이름이 변경되었습니다. |
signOut | SIGN_OUT | 이름이 변경되었습니다. |
viewHome | HOME_VIEWED | 이름이 변경되었습니다. |
viewProductList | PRODUCT_LIST_VIEWED | 이름이 변경되었습니다. |
viewSearchResult | SEARCH_RESULTS_VIEWED | 이름이 변경되었습니다. |
viewProductDetail | PRODUCT_VIEWED | 이름이 변경되었습니다. |
- | ADD_PAYMENT_INFO | 새로운 기능이 추가되었습니다. |
- | ADD_TO_WISHLIST | 새로운 기능이 추가되었습니다. |
addToCart | ADDED_TO_CART | 이름이 변경되었습니다. |
- | INITIATE_CHECKOUT | 새로운 기능이 추가되었습니다. |
purchase | ORDER_COMPLETED | 이름이 변경되었습니다. |
- | ORDER_CANCELED | 새로운 기능이 추가되었습니다. |
- | START_TRIAL | 새로운 기능이 추가되었습니다. |
- | SUBSCRIBE | 새로운 기능이 추가되었습니다. |
- | UNSUBSCRIBE | 새로운 기능이 추가되었습니다. |
- | AD_IMPRESSION | 새로운 기능이 추가되었습니다. |
- | AD_CLICK | 새로운 기능이 추가되었습니다. |
- | COMPLETE_TUTORIAL | 새로운 기능이 추가되었습니다. |
- | ACHIEVE_LEVEL | 새로운 기능이 추가되었습니다. |
- | UNLOCK_ACHIEVEMENT | 새로운 기능이 추가되었습니다. |
- | RATE | 새로운 기능이 추가되었습니다. |
- | SHARE | 새로운 기능이 추가되었습니다. |
- | SCHEDULE | 새로운 기능이 추가되었습니다. |
- | SPEND_CREDITS | 새로운 기능이 추가되었습니다. |
ABSemanticsKey | AirbridgeAttribute | 변경점 |
---|---|---|
- | ACTION | 새로운 기능이 추가되었습니다. |
- | LABEL | 새로운 기능이 추가되었습니다. |
- | VALUE | 새로운 기능이 추가되었습니다. |
totalValue | - | 기능이 제거되었습니다. VALUE에 입력해주세요. |
currency | CURRENCY | 이름이 변경되었습니다. |
- | ORIGINAL_CURRENCY | 새로운 기능이 추가되었습니다. |
products | PRODUCTS | 이름이 변경되었습니다. |
- | PERIOD | 새로운 기능이 추가되었습니다. |
- | IS_RENEWAL | 새로운 기능이 추가되었습니다. |
- | RENEWAL_COUNT | 새로운 기능이 추가되었습니다. |
productListID | PRODUCT_LIST_ID | 이름이 변경되었습니다. |
cartID | CART_ID | 이름이 변경되었습니다. |
transactionID | TRANSACTION_ID | 이름이 변경되었습니다. |
- | TRANSACTION_TYPE | 새로운 기능이 추가되었습니다. |
- | TRANSACTION_PAIRED_EVENT_CATEGORY | 새로운 기능이 추가되었습니다. |
- | TRANSACTION_PAIRED_EVENT_TIMESTAMP | 새로운 기능이 추가되었습니다. |
totalQuantity | TOTAL_QUANTITY | 이름이 변경되었습니다. |
query | QUERY | 이름이 변경되었습니다. |
inAppPurchased | IN_APP_PURCHASED | 이름이 변경되었습니다. |
- | CONTRIBUTION_MARGIN | 새로운 기능이 추가되었습니다. |
- | ORIGINAL_CONTRIBUTION_MARGIN | 새로운 기능이 추가되었습니다. |
- | LIST_ID | 새로운 기능이 추가되었습니다. |
- | RATE_ID | 새로운 기능이 추가되었습니다. |
- | RATE | 새로운 기능이 추가되었습니다. |
- | MAX_RATE | 새로운 기능이 추가되었습니다. |
- | ACHIEVEMENT_ID | 새로운 기능이 추가되었습니다. |
- | SHARED_CHANNEL | 새로운 기능이 추가되었습니다. |
- | DATE_TIME | 새로운 기능이 추가되었습니다. |
- | DESCRIPTION | 새로운 기능이 추가되었습니다. |
- | IS_REVENUE | 새로운 기능이 추가되었습니다. |
- | PLACE | 새로운 기능이 추가되었습니다. |
- | SCHEDULE_ID | 새로운 기능이 추가되었습니다. |
- | TYPE | 새로운 기능이 추가되었습니다. |
- | LEVEL | 새로운 기능이 추가되었습니다. |
- | SCORE | 새로운 기능이 추가되었습니다. |
- | AD_PARTNERS | 새로운 기능이 추가되었습니다. |
- | IS_FIRST_PER_USER | 새로운 기능이 추가되었습니다. |
ABProductKey | AirbridgeAttribute | 변경점 |
---|---|---|
productID | PRODUCT_ID | 이름이 변경되었습니다. |
name | PRODUCT_NAME | 이름이 변경되었습니다. |
price | PRODUCT_PRICE | 이름이 변경되었습니다. |
quantity | PRODUCT_QUANTITY | 이름이 변경되었습니다. |
currency | PRODUCT_CURRENCY | 이름이 변경되었습니다. |
position | PRODUCT_POSITION | 이름이 변경되었습니다. |
- | PRODUCT_CATEGORY_ID | 새로운 기능이 추가되었습니다. |
- | PRODUCT_CATEGORY_NAME | 새로운 기능이 추가되었습니다. |
- | PRODUCT_BRAND_ID | 새로운 기능이 추가되었습니다. |
- | PRODUCT_BRAND_NAME | 새로운 기능이 추가되었습니다. |
CocoaPods 패키지명, SwiftPackageManager Git 주소, 직접 설치 다운로드 URL 등이 변경되었습니다. 기존 iOS SDK를 삭제한 후에 에어브릿지 가이드에 따라 다시 설치해 주세요.
SDK 초기화에 사용하는 AirBridge.getInstance
함수가 Airbridge.initializeSDK
함수로 변경되었습니다. 또한 옵션 설정 함수가 AirbridgeOption
, AirbridgeOptionBuilder
클래스들로 변경되었습니다. SDK의 옵션은 더는 런타임에 변경되지 않습니다.
아래 맵핑을 참고해 새로운 SDK 초기화 코드를 작성해 주세요.
import Airbridge
...
let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
.setLogLevel(.warning)
.setSessionTimeout(second: 300)
.build()
Airbridge.initializeSDK(option: option)
#import <Airbridge/Airbridge.h>
...
AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
token:@"YOUR_APP_SDK_TOKEN"];
[optionBuilder setLogLevel:AirbridgeLogLevelWarning];
[optionBuilder setSessionTimeoutWithSecond:300];
AirbridgeOption* option = [optionBuilder build];
[Airbridge initializeSDKWithOption:option];
AirBridge | Default | AirbridgeOptionBuilder | Default |
---|---|---|---|
setLogLevel(ABLogLevel) | LOG_WARNING | setLogLevel(AirbridgeLogLevel) | .warning |
setSDKEnabled(Bool) | true | setSDKEnabled(Bool) | true |
setIsFacebookDeferredAppLinkEnabled(Bool) | false | setTrackMetaDeferredAppLinkEnabled(Bool) | false |
setAutoStartTrackingEnabled(Bool) | true | setAutoStartTrackingEnabled(Bool) | true |
setting().trackingAuthorizeTimeout // UInt | 30000 (millisecond) | setAutoDetermineTrackingAuthorizationTimeout(second: Double) | 300.0 (second) (0 ~ 1 hour) |
setting().isRestartTrackingAuthorizeTimeout // Bool | true | 기능이 제거되었습니다. | - |
deeplink().setDeeplinkCallback((String) -> Void) | - | 다른 기능으로 대체되었습니다. 딥링크 항목을 참고해주세요. | - |
deeplink().setDeferredDeeplinkCallback((String) -> Void) | - | 다른 기능으로 대체되었습니다. 딥링크 항목을 참고해주세요. | - |
deeplink().setHandleTrackingLinkTimeout(UInt) | 3000 (millisecond) | 기능이 제거되었습니다. (3초 고정) | - |
setIsUserInfoHashed(Bool) | true | setHashUserInformationEnabled(Bool) | true |
setSessionTimeout(Int) | 300000 (millisecond) | setSessionTimeout(second: Double) | 300.0 (second) (0 ~ 7 day) |
setting().setTrackInSessionLifeCycleEventEnabled(Bool) | false | setTrackInSessionLifecycleEventEnabled(Bool) | false |
setIsTrackAirbridgeDeeplinkOnly(Bool) | false | setTrackAirbridgeDeeplinkOnlyEnabled(Bool) | false |
setSDKSignatureSecret(id: String, secret: String) | - | setSDKSignature(id: String, secret: String) | - |
setResetEventBufferEnabled(Bool) | false | setClearEventBufferOnInitializeEnabled(Bool) | false |
setting().isResetEventBufferEnabled // Bool | false | setClearEventBufferOnInitializeEnabled(Bool) | false |
setting().setEventMaximumBufferCount(UInt) | INT_MAX | setEventBufferCountLimit(Int) | INT_MAX |
setting().setEventMaximumBufferCount(UInt) | INT_MAX (byte) | setEventBufferSizeLimit(gibibyte: Double) | 1024 (gibibyte) (0 ~ 1 tebibyte) |
setting().setEventTransmitInterval(UInt) | 0 (millisecond) | setEventTransmitInterval(second: Double) | 0 (second) (0 ~ 1 day) |
setting().attributionCallback(([String: String]) -> Void) | - | setOnAttributionReceived(([String: String]) -> Void) | - |
import Airbridge
...
let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
.setLogLevel(.warning)
.setSessionTimeout(second: 300)
.build()
Airbridge.initializeSDK(option: option)
#import <Airbridge/Airbridge.h>
...
AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
token:@"YOUR_APP_SDK_TOKEN"];
[optionBuilder setLogLevel:AirbridgeLogLevelWarning];
[optionBuilder setSessionTimeoutWithSecond:300];
AirbridgeOption* option = [optionBuilder build];
[Airbridge initializeSDKWithOption:option];
AirBridge.setDeeplinkCallback
함수가 Airbridge.handleDeeplink
함수와 handleDeferredDeeplink
함수로 대체되었습니다.
기존 AirBridge.setDeeplinkCallback
함수를 에어브릿지 대시보드에 등록한 스킴딥링크를 처리하는 함수와 다른 딥링크를 처리하는 함수로 분리해 구현해야 합니다. 아래 DeeplinkHandler 클래스를 참고해 주세요.
import Foundation
final class DeeplinkHandler {
private init() {}
static func handleSchemeDeeplink(url: URL) -> Bool {
if url.scheme != "YOUR_SCHEME" {
return false
}
// REQUIRE: show content
return true
}
static func handleOtherDeeplink(url: URL) -> Bool {
// OPTION: show content
return true
}
}
#import <Foundation/Foundation.h>
@implementation ABDeeplinkHandler
- (instancetype) init __unavailable;
+ (BOOL)handleSchemeDeeplink:(NSURL *)url;
+ (BOOL)handleOtherDeeplink:(NSURL *)url;
@end
...
#import "ABDeeplinkHandler.h"
@interface ABDeeplinkHandler : NSObject
+ (BOOL)handleSchemeDeeplink:(NSURL *)url {
if (![url.scheme isEqualToString:@"YOUR_SCHEME"]) {
return NO;
}
// REQUIRE: show content
return YES;
}
+ (BOOL)handleOtherDeeplink:(NSURL *)url {
// OPTION: show content
return YES;
}
@end
AirBridge.deeplink().handle
(또는 handleUniversalLink
)와 AirBridge.deeplink().handleURLSchemeDeeplink
는 Airbridge.trackDeeplink
로 대체되었습니다.
1. 시스템 방식에 따라 AirBridge.deeplink().handle
(또는 handleUniversalLink
)와 AirBridge.deeplink().handleURLSchemeDeeplink
함수를 호출하는 부분을 삭제합니다.
2. Airbridge.trackDeeplink
함수와 Airbridge.handleDeeplink
함수를 호출합니다.
Airbridge.handleDeeplink
함수는 에어브릿지 딥링크가 입력되면 true와 함께 스킴 딥링크를 콜백으로 제공합니다. 에어브릿지 딥링크가 아니면 false와 함께 콜백을 제공하지 않습니다.
3. onSuccess
콜백에서 에어브릿지로 실행된 스킴 딥링크를 처리하는 함수를 호출합니다.
import UIKit
import Airbridge
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
// when terminated app is opened with scheme deeplink or universal links
func scene(
_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions
) {
// when app is opened with scheme deeplink
if let url = connectionOptions.urlContexts.first?.url {
// track deeplink
Airbridge.trackDeeplink(url: url)
// handle airbridge deeplink
var isHandled = Airbridge.handleDeeplink(url: url) { url in
DeeplinkHandler.handleSchemeDeeplink(url: url)
}
if isHandled { return }
// handle scheme deeplink
isHandled = DeeplinkHandler.handleSchemeDeeplink(url: url)
if isHandled { return }
// handle other deeplink
isHandled = DeeplinkHandler.handleOtherDeeplink(url: url)
}
// when app is opened with universal links
else if let userActivity = connectionOptions.userActivities.first {
// track deeplink
Airbridge.trackDeeplink(userActivity: userActivity)
// handle airbridge deeplink
var isHandled = Airbridge.handleDeeplink(userActivity: userActivity) { url in
DeeplinkHandler.handleSchemeDeeplink(url: url)
}
if isHandled { return }
// handle other deeplink
if let url = userActivity.webpageURL {
isHandled = DeeplinkHandler.handleOtherDeeplink(url: url)
}
}
}
// when backgrounded app is opened with scheme deeplink
func scene(
_ scene: UIScene,
openURLContexts URLContexts: Set<UIOpenURLContext>
) {
guard let url = URLContexts.first?.url else { return }
// track deeplink
Airbridge.trackDeeplink(url: url)
// handle airbridge deeplink
var isHandled = Airbridge.handleDeeplink(url: url) { url in
DeeplinkHandler.handleSchemeDeeplink(url: url)
}
if isHandled { return }
// handle scheme deeplink
isHandled = DeeplinkHandler.handleSchemeDeeplink(url: url)
if isHandled { return }
// handle other deeplink
isHandled = DeeplinkHandler.handleOtherDeeplink(url: url)
}
// when backgrounded app is opened with universal links
func scene(
_ scene: UIScene,
continue userActivity: NSUserActivity
) {
// track deeplink
Airbridge.trackDeeplink(userActivity: userActivity)
// handle airbridge deeplink
var isHandled = Airbridge.handleDeeplink(userActivity: userActivity) { url in
DeeplinkHandler.handleSchemeDeeplink(url: url)
}
if isHandled { return }
// handle other deeplink
if let url = userActivity.webpageURL {
isHandled = DeeplinkHandler.handleOtherDeeplink(url: url)
}
}
}
#import "SceneDelegate.h"
#import "ABDeeplinkHandler.h"
#import <Airbridge/Airbridge.h>
@interface SceneDelegate ()
@end
@implementation SceneDelegate
// when terminated app is opened with scheme deeplink or universal links
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
// when app is opened with scheme deeplink
NSURL* url = connectionOptions.URLContexts.allObjects.firstObject.URL;
NSUserActivity* userActivity = connectionOptions.userActivities.allObjects.firstObject;
if (url != nil) {
// track deeplink
[Airbridge trackDeeplinkWithUrl:url];
// handle airbridge deeplink
BOOL isHandled = [Airbridge handleDeeplinkWithUrl:url onSuccess:^(NSURL* url) {
[ABDeeplinkHandler handleSchemeDeeplink:url];
}];
if (isHandled) { return; }
// handle scheme deeplink
isHandled = [ABDeeplinkHandler handleSchemeDeeplink:url];
if (isHandled) { return; }
// handle other deeplink
isHandled = [ABDeeplinkHandler handleSchemeDeeplink:url];
}
else if (userActivity != nil) {
// track deeplink
[Airbridge trackDeeplinkWithUserActivity:userActivity];
// handle airbridge deeplink
BOOL isHandled = [Airbridge handleDeeplinkWithUserActivity:userActivity onSuccess:^(NSURL* url) {
[ABDeeplinkHandler handleSchemeDeeplink:url];
}];
if (isHandled) { return; }
// handle other deeplink
NSURL* url = userActivity.webpageURL;
if (url != nil) {
isHandled = [ABDeeplinkHandler handleOtherDeeplink:url];
}
}
}
// when backgrounded app is opened with scheme deeplink
- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts {
NSURL* url = URLContexts.allObjects.firstObject.URL;
if (url == nil) { return; }
// track deeplink
[Airbridge trackDeeplinkWithUrl:url];
// handle airbridge deeplink
BOOL isHandled = [Airbridge handleDeeplinkWithUrl:url onSuccess:^(NSURL* url) {
[ABDeeplinkHandler handleSchemeDeeplink:url];
}];
if (isHandled) { return; }
// handle scheme deeplink
isHandled = [ABDeeplinkHandler handleSchemeDeeplink:url];
if (isHandled) { return; }
// handle other deeplink
isHandled = [ABDeeplinkHandler handleSchemeDeeplink:url];
}
// when backgrounded app is opened with universal links
- (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity {
// track deeplink
[Airbridge trackDeeplinkWithUserActivity:userActivity];
// handle airbridge deeplink
BOOL isHandled = [Airbridge handleDeeplinkWithUserActivity:userActivity onSuccess:^(NSURL* url) {
[ABDeeplinkHandler handleSchemeDeeplink:url];
}];
if (isHandled) { return; }
// handle other deeplink
NSURL* url = userActivity.webpageURL;
if (url != nil) {
isHandled = [ABDeeplinkHandler handleOtherDeeplink:url];
}
}
@end
import SwiftUI
import Airbridge
@main
struct ActualApp: App {
var body: some Scene {
WindowGroup {
ContentView()
// when app is opened with scheme deeplink or universal links
.onOpenURL { url in
// track deeplink
Airbridge.trackDeeplink(url: url)
// handle airbridge deeplink
var isHandled = Airbridge.handleDeeplink(url: url) { url in
DeeplinkHandler.handleSchemeDeeplink(url: url)
}
if isHandled { return }
// handle scheme deeplink
isHandled = DeeplinkHandler.handleSchemeDeeplink(url: url)
if isHandled { return }
// handle other deeplink
isHandled = DeeplinkHandler.handleOtherDeeplink(url: url)
}
}
}
}
import UIKit
import Airbridge
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
// when app is opened with scheme deeplink
func application(
_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey : Any] = [:]
) -> Bool {
// track deeplink
Airbridge.trackDeeplink(url: url)
// handle airbridge deeplink
var isHandled = Airbridge.handleDeeplink(url: url) { url in
DeeplinkHandler.handleSchemeDeeplink(url: url)
}
if isHandled { return isHandled }
// handle scheme deeplink
isHandled = DeeplinkHandler.handleSchemeDeeplink(url: url)
if isHandled { return isHandled }
// handle other deeplink
isHandled = DeeplinkHandler.handleOtherDeeplink(url: url)
return isHandled
}
// when app is opened with universal links
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
// track deeplink
Airbridge.trackDeeplink(userActivity: userActivity)
// handle airbridge deeplink
var isHandled = Airbridge.handleDeeplink(userActivity: userActivity) { url in
DeeplinkHandler.handleSchemeDeeplink(url: url)
}
if isHandled { return isHandled }
// handle other deeplink
if let url = userActivity.webpageURL {
isHandled = DeeplinkHandler.handleOtherDeeplink(url: url)
}
return isHandled
}
}
#import "AppDelegate.h"
#import "ABDeeplinkHandler.h"
#import <Airbridge/Airbridge.h>
@interface AppDelegate ()
@end
@implementation AppDelegate
// when app is opened with scheme deeplink
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
// track deeplink
[Airbridge trackDeeplinkWithUrl:url];
// handle airbridge deeplink
BOOL isHandled = [Airbridge handleDeeplinkWithUrl:url onSuccess:^(NSURL* url) {
[ABDeeplinkHandler handleSchemeDeeplink:url];
}];
if (isHandled) { return isHandled; }
// handle scheme deeplink
isHandled = [ABDeeplinkHandler handleSchemeDeeplink:url];
if (isHandled) { return isHandled; }
// handle other deeplink
isHandled = [ABDeeplinkHandler handleOtherDeeplink:url];
return isHandled;
}
// when app is opened with universal links
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
// track deeplink
[Airbridge trackDeeplinkWithUserActivity:userActivity];
// handle airbridge deeplink
BOOL isHandled = [Airbridge handleDeeplinkWithUserActivity:userActivity onSuccess:^(NSURL* url) {
[ABDeeplinkHandler handleSchemeDeeplink:url];
}];
if (isHandled) { return isHandled; }
// handle other deeplink
NSURL* url = userActivity.webpageURL;
if (url != nil) {
isHandled = [ABDeeplinkHandler handleOtherDeeplink:url];
}
return isHandled;
}
@end
Airbridge.handleDeeplink
함수는 에어브릿지 딥링크가 입력되면 true를 반환하고 Scheme 딥링크로 변환하여onSuccess
에 전달합니다. 그리고 에어브릿지 딥링크가 아닌 URL이 입력되거나 SDK가 초기화되지 않았으면 false를 반환하기만 합니다.
SDK를 초기화하는 부분에서Airbridge.handleDeferredDeeplink
함수를 호출합니다. onSuccess
콜백에서 에어브릿지로 실행된 스킴 딥링크를 처리하는 함수를 호출합니다.
import Airbridge
...
let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
.build()
Airbridge.initializeSDK(option: option)
...
let isHandled = Airbridge.handleDeferredDeeplink() { url in
if let url {
DeeplinkHandler.handleSchemeDeeplink(url)
}
}
#import <Airbridge/Airbridge.h>
...
AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
token:@"YOUR_APP_SDK_TOKEN"];
AirbridgeOption* option = [optionBuilder build];
[Airbridge initializeSDKWithOption:option];
...
[Airbridge handleDeferredDeeplinkOnSuccess:^(NSURL* url) {
if (url != nil) {
[ABDeeplinkHandler handleSchemeDeeplink:url];
}
}];
Airbridge.handleDeferredDeeplink
함수는 에어브릿지 딥링크가 입력되면 true와 함께 에어브릿지 딥링크 획득을 기다리거나 스킴 딥링크로 변환해 onSuccess로 전달합니다. 해당 스킴 딥링크를 활용해 유저를 설정한 목적지로 보낼 수 있습니다.
또는 저장된 에어브릿지 딥링크가 없으면 nil을 전달합니다. SDK가 초기화되지 않았거나 Airbridge.handleDeferredDeeplink
함수를 처음으로 호출하지 않았다면 false를 전달합니다.
커스텀 도메인을 등록하는 방법이 변경되었습니다. 기존에는 Info.plist의 co.ab180.airbridge.trackingLink.customDomains
키에 커스텀 도메인을 밸류로 추가했습니다.
변경된 방식은 SDK 초기화 단계에서 setTrackingLinkCustomDomains
함수를 호출하여 추가하는 방식입니다.
SDK 초기화 코드에서 setTrackingLinkCustomDomains
함수를 호출해 주세요.
import Airbridge
...
let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_TOKEN")
.setTrackingLinkCustomDomains(["YOUR_CUSTOM_DOMAIN"])
.build()
Airbridge.initializeSDK(option: option)
#import <Airbridge/Airbridge.h>
...
AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
token:@"YOUR_APP_TOKEN"];
[optionBuilder setTrackingLinkCustomDomains:@[@"YOUR_CUSTOM_DOMAIN"]];
AirbridgeOption* option = [optionBuilder build];
[Airbridge initializeSDKWithOption:option];
주의하세요
기존 totalValue 대신 AirbridgeAttribute.VALUE에 값을 입력해 주세요.
setSemantics의 totalValue를 사용하고 setValue로 밸류를 정의하면 totalValue가 밸류를 덮어 쓰는 로직은 iOS SDK v4부터 삭제되었습니다.
ABInAppEvent 클래스가 Airbridge.trackEvent
함수로 대체되었습니다.
아래 가이드에 따라 ABInAppEvent 클래스와 setAction, setLabel, setValue, setSemantics, setCustoms를 Airbridge.trackEvent
함수로 변경해 주세요.
setCategory: ABCategory를 사용하고 있다면 AirbridgeCategory를 사용해야 합니다. String을 사용하고 있다면 그대로 category 파라미터에 입력합니다.
setAction: semanticAttributes 파라미터의 AirbridgeAttribute.ACTION 키에 입력합니다.
setLabel: semanticAttributes 파라미터의 AirbridgeAttribute.LABEL 키에 입력합니다.
setValue: semanticAttributes 파라미터의 AirbridgeAttribute.VALUE 키에 입력합니다.
setSemantics: semanticAttributes 파라미터에 키로 ABSemanticsKey를 사용하고 있다면 AirbridgeAttribute를 사용합니다. String을 사용하고 있다면 그대로 입력합니다. 밸류는 키와 관계 없이 그대로 입력합니다.
setCustoms: customAttributes 파라미터에 키, 밸류를 그대로 입력합니다.
아래에서 AirbridgeCategory, AirbridgeAttribute 매핑과 Airbridge.trackEvent 함수를 참고해 주세요.
ABCategory | AirbridgeCategory |
---|---|
signIn | SIGN_IN |
signUp | SIGN_UP |
signOut | SIGN_OUT |
viewHome | HOME_VIEWED |
viewProductList | PRODUCT_LIST_VIEWED |
viewSearchResult | SEARCH_RESULTS_VIEWED |
viewProductDetail | PRODUCT_VIEWED |
addToCart | ADDED_TO_CART |
purchase | ORDER_COMPLETED |
ABSemanticsKey | AirbridgeAttribute |
---|---|
products | PRODUCTS |
transactionID | TRANSACTION_ID |
inAppPurchased | IN_APP_PURCHASED |
cartID | CART_ID |
query | QUERY |
productListID | PRODUCT_LIST_ID |
currency | CURRENCY |
totalValue | 제거되었습니다. VALUE에 입력해주세요. |
totalQuantity | TOTAL_QUANTITY |
ABProductKey | AirbridgeAttribute |
---|---|
productID | PRODUCT_ID |
name | PRODUCT_NAME |
price | PRODUCT_PRICE |
currency | PRODUCT_CURRENCY |
position | PRODUCT_POSITION |
quantity | PRODUCT_QUANTITY |
import Airbridge
...
// setCategory
Airbridge.trackEvent(
category: AirbridgeCategory.ORDER_COMPLETED,
semanticAttributes: [
// setAction
AirbridgeAttribute.ACTION: "Tool",
// setLabel
AirbridgeAttribute.LABEL: "Hammer",
// setValue
AirbridgeAttribute.VALUE: 10,
// setSemantics (using ABSemanticsKey)
AirbridgeAttribute.CURRENCY: "USD",
AirbridgeAttribute.PRODUCTS: [
[
// setSemantics value (using ABProductKey)
AirbridgeAttribute.PRODUCT_ID: "12345",
// setSemantics value (using String)
"name": "PlasticHammer",
],
],
// setSemantics (using String)
"totalQuantity": 1,
],
customAttributes: [
// setCustoms
"promotion": "FirstPurchasePromotion",
]
)
#import <Airbridge/Airbridge.h>
...
[Airbridge trackEventWithCategory:@"event" semanticAttributes:@{
// action
AirbridgeAttribute.ACTION: @"Tool",
// label
AirbridgeAttribute.LABEL: @"Hammer",
// value
AirbridgeAttribute.VALUE: @(10),
// semantic attribute (provided by sdk)
AirbridgeAttribute.CURRENCY: @"USD",
AirbridgeAttribute.PRODUCTS: @[
@{
// semantic attribute value (provided by sdk)
AirbridgeAttribute.PRODUCT_ID: @"12345",
// semantic attribute value (not provided by sdk)
@"name": @"PlasticHammer",
},
],
// semantic attribute (not provided by sdk)
@"totalQuantity": @(1),
}, customAttributes:@{
// custom attribute
@"promotion": @"FirstPurchasePromotion",
}];
AirBridge.setDeviceAlias
관련 함수가 Airbridge.setDeviceAlias 관련 함수로 대체되었습니다.
import Airbridge
...
Airbridge.setDeviceAlias(key: "string", value: "string")
Airbridge.removeDeviceAlias(key: "string")
Airbridge.clearDeviceAlias()
#import <Airbridge/Airbridge.h>
...
BOOL isHandled = [Airbridge impressionWithTrackingLink:url onSuccess:^{
// when url is tracking link and succeed
} onFailure:^(NSError * _Nonnull) {
// when url is tracking link and failed
}];
if (!isHandled) {
// when url is not tracking link
}
AirBridge.state().setUser
관련 함수가 Airbridge.setUser 관련 함수로 대체되었습니다. 유저 정보를 한번에 설정하는 setUser
함수는 지원하지 않습니다.
import Airbridge
...
// identifier
Airbridge.setUserID("string")
Airbridge.clearUserID()
// addtional identifier
Airbridge.setUserAlias(key: "string", value: "string")
Airbridge.removeUserAlias(key: "string")
Airbridge.clearUserAlias()
...
// email, phone
Airbridge.setUserEmail("string")
Airbridge.clearUserEmail()
Airbridge.setUserPhone("string")
Airbridge.clearUserPhone()
// addtional attribute
Airbridge.setUserAttribute(key: "string", value: "string")
Airbridge.setUserAttribute(key: "number", value: 1000)
Airbridge.removeUserAttribute(key: "string")
Airbridge.clearUserAttributes()
#import <Airbridge/Airbridge.h>
...
// identifier
[Airbridge setUserID:@"string"];
[Airbridge clearUserID];
// additional identifier
[Airbridge setUserAliasWithKey:@"string" value:@"string"];
[Airbridge removeUserAliasWithKey:@"string"];
[Airbridge clearUserAlias];
...
// email, phone
[Airbridge setUserEmail:@"string"];
[Airbridge clearUserEmail];
[Airbridge setUserPhone:@"string"];
[Airbridge clearUserPhone];
// addtional attribute
[Airbridge setUserAttributeWithKey:@"string" value:@"string"];
[Airbridge setUserAttributeWithKey:@"number" value:@(1000)];
[Airbridge removeUserAttributeWithKey:@"string"];
[Airbridge clearUserAttributes];
AirBridge.placement().click
함수와 AirBridge.placement().impression
함수가 Airbridge.click
함수와 Airbridge.impression
함수로 대체되었습니다.
import Airbridge
...
let isHandled = Airbridge.click(trackingLink: url) {
// when url is tracking link and succeed
} onFailure: { error in
// when url is tracking link and failed
// example: url is another app's tracking link, internet is not connected
}
if !isHandled {
// when url is not tracking link
}
...
let isHandled = Airbridge.impression(trackingLink: url) {
// when url is tracking link and succeed
} onFailure: { error in
// when url is tracking link and failed
}
if !isHandled {
// when url is not tracking link
}
#import <Airbridge/Airbridge.h>
...
BOOL isHandled = [Airbridge clickWithTrackingLink:url onSuccess:^{
// when url is tracking link and succeed
} onFailure:^(NSError * _Nonnull) {
// when url is tracking link and failed
// example: url is another app's tracking link, internet is not connected
}];
if (!isHandled) {
// when url is not tracking link
}
...
BOOL isHandled = [Airbridge impressionWithTrackingLink:url onSuccess:^{
// when url is tracking link and succeed
} onFailure:^(NSError * _Nonnull) {
// when url is tracking link and failed
}];
if (!isHandled) {
// when url is not tracking link
}
AirBridge.webInterface().inject
함수가 Airbridge.setWebInterface
함수로 대체되었습니다.
import Airbridge
...
Airbridge.setWebInterface(
controller: controller,
webToken: "YOUR_WEB_TOKEN"
)
#import <Airbridge/Airbridge.h>
...
[Airbridge setWebInterfaceWithController:controller webToken:@"YOUR_WEB_TOKEN"];
iOS SDK 각 버전의 주요 변경사항을 참고해 주세요.
2023년 9월 4일 이후 생성된 에어브릿지 앱은 딥링크 콜백에서 제공되는 딥링크 URL이 에어브릿지 대시보드에 입력된 내용을 2번 디코딩해 제공하는 문제를 해결했습니다.
해당 문제는 iOS SDK v1.34.0 ~ 1.35.1에서 발생했습니다.
2023년 9월 4일 이후 생성된 에어브릿지 앱은 딥링크 콜백에 제공되는 딥링크 URL에 airbridge_referrer를 추가하지 않고 에어브릿지 대시보드에 입력한 정보로 전달됩니다.
2023년 9월 4일 이전에 생성된 에어브릿지 앱을 사용하는 고객사 중에서 해당 기능이 필요한 고객사는 에어브릿지 CSM에게 요청해 주세요. 담당 CSM이 없는 경우 문의하기를 통해 요청해 주세요.
SKAdNetwork 4.0을 지원하면서 전환값 계산 방식이 변경되었습니다. 유저가 iOS SDK v1.33.0 미만을 설치한 앱에서 v1.33.0 이상이 있는 앱으로 업데이트하면 마지막에 계산된 전환값을 최종 값으로 확정합니다.
trackingAuthorizeTimeout
의 기본 설정이 0초에서 30초로 변경되었습니다.
도움이 되었나요?