> ## Documentation Index
> Fetch the complete documentation index at: https://help.airbridge.io/llms.txt
> Use this file to discover all available pages before exploring further.

# iOS SDK

![GitHub Tag](https://img.shields.io/github/v/tag/ab180/airbridge-ios-sdk-deployment?style=flat\&label=Airbridge%20iOS%20SDK)

에어브릿지 iOS SDK를 설치하고 필요한 설정을 추가할 수 있습니다.

## iOS SDK 설치하기

에어브릿지 iOS SDK는 아래 방법으로 설치할 수 있습니다. 설치한 이후에 [iOS SDK 테스트](/ko/developers/testing-ios-sdk-v4)로 SDK가 정상적으로 설치됐는지 확인할 수 있습니다.

<Tabs>
  <Tab title="SwiftPackageManager">
    1. Xcode에서 \[File]에서 \[Add Packages...]를 클릭해 주세요.

    2. 검색창에 아래 주소를 입력하고 \[Add Package]를 클릭합니다.
       * [https://github.com/ab180/airbridge-ios-sdk-deployment](https://github.com/ab180/airbridge-ios-sdk-deployment)

    3. \[Add Package]를 계속해서 클릭합니다.

    4. Xcode의 \[Package Dependencies]에서 에어브릿지 iOS SDK 추가를 확인할 수 있습니다.
  </Tab>

  <Tab title="CocoaPods">
    <Danger>
      **주의하세요**

      \[Xcode]>\[YOUR\_PROJECT]>\[Build Settings]>\[User Script Sandboxing]을 No로 설정한 후에 iOS SDK를 설치해야 합니다. 자세한 내용은 [CocoaPods 문서](https://github.com/CocoaPods/CocoaPods/issues/11946)를 참고해 주세요.
    </Danger>

    1. `brew install cocoapods` 로 CocoaPods를 설치합니다.
    2. `pod init`로 Podfile을 생성합니다.
    3. Podfile에 아래 코드로 SDK를 의존성으로 추가합니다. 그리고 아래 링크에서 최신버전을 확인하고 `$HERE_LATEST_VERSION` 에 입력하세요.
       * SDK 버전 목록: [링크](/ko/developers/release-note-ios-sdk)

    ```ruby Podfile lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    target '[Project Name]' do
        ...
        # Replace $HERE_LATEST_VERSION with latest version
        # - Versions: https://help.airbridge.io/developers/release-note-ios-sdk
        # - Example: pod 'airbridge-ios-sdk', '4.X.X'
        pod 'airbridge-ios-sdk', '$HERE_LATEST_VERSION'
        ...
    end
    ```

    4. `pod install --repo-update`를 입력하면 설치가 진행됩니다
    5. `YOUR_PROJECT.xcworkspace`를 실행하면 에어브릿지 iOS SDK가 정상적으로 설치된 것을 확인할 수 있습니다.
  </Tab>

  <Tab title="Tuist">
    <Danger>
      **주의하세요**

      Tuist의 [Tuist's XcodeProj-based integration](https://docs.tuist.dev/en/guides/develop/projects/dependencies#tuists-xcodeprojbased-integration) 방식으로는 에어브릿지 iOS SDK를 설치할 수 없습니다. 반드시 [Xcode's default integration](https://docs.tuist.dev/en/guides/develop/projects/dependencies#xcodes-default-integration) 방식으로 설치해 주세요.
    </Danger>

    1. `tuist edit` 명령어를 실행합니다.
    2. `project.packages`에 `remote`를 추가합니다. SDK를 `project.targets[...].target.dependencies`에 `package`로, 의존성 Framework를 `sdk`로 추가합니다. 그리고 아래 링크에서 최신버전을 확인하고 `$HERE_LATEST_VERSION` 에 입력하세요.
       * SDK 버전 목록: [링크](/ko/developers/release-note-ios-sdk)

    * 의존성 Framework 목록

    | Framework                         | 설명                                            |
    | --------------------------------- | --------------------------------------------- |
    | AdSupport.framework               | IDFA를 수집하는데 사용합니다.                            |
    | CoreTelephony.framework           | 통신사 정보를 수집하는데 사용합니다.                          |
    | StoreKit.framework                | SKAdNetwork 정보를 수집하는데 사용합니다.                  |
    | AppTrackingTransparency.framework | 추적 허용 상태정보를 수집하는데 사용합니다.                      |
    | AdServices.framework              | Apple Ads의 어트리뷰션 정보를 수집하는데 사용합니다. (iOS 14.3+) |
    | WebKit.framework                  | Web SDK와 연동하여 이벤트를 수집하는데 사용합니다.               |

    ```swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    import ProjectDescription

    let project = Project(
        packages: [
            .remote(
                url: "https://github.com/ab180/airbridge-ios-sdk-deployment",
                // Replace $HERE_LATEST_VERSION with latest version
                // - Versions: https://help.airbridge.io/developers/release-note-ios-sdk
                // - Example: requirement: .exact(from: "4.X.X")
                requirement: .exact(from: "$HERE_LATEST_VERSION")
            ),
            ...
        ],
        targets: [
            .target(
                dependencies: [
                    .package(product: "Airbridge", type: .runtime),
                    .sdk(name: "AdSupport", 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),
                    ...
                ]
            ),
            ...
        ],
        ...
    )
    ```

    3. `tuist generate` 명령어를 실행합니다.
    4. Xcode의 Package Dependencies에 Airbridge가 추가됩니다.
  </Tab>

  <Tab title="직접 설치">
    1. 아래 링크에서 에어브릿지 iOS SDK를 다운로드합니다.
       * [https://sdk-download.airbridge.io/airbridge-ios-sdk/latest/Airbridge.zip](https://sdk-download.airbridge.io/airbridge-ios-sdk/latest/Airbridge.zip)

    2. Airbridge.xcframework를 프로젝트에 추가합니다. \[Xcode]>\[프로젝트 파일]>\[General]>\[Frameworks, Libraries, and Embedded Content]에서 ‘+’를 클릭합니다.

    3. \[Add Other...]에서 ‘Add Files...’를 클릭하고 Airbridge.xcframework를 선택합니다.

    4. Airbridge.xcframework의 Embed를 Embed & Sign로 설정합니다.
  </Tab>
</Tabs>

### 디바이스 ID를 수집하지 않는 SDK

<Info>
  **알립니다**

  일반 SDK와 제한된 SDK 중에서 1가지 버전만 설치해 주세요.
</Info>

정책, 환경 등에 따라 GAID, IDFA 같은 [디바이스 ID](/ko/guides/identifiers) 수집에 제한이 필요할 수 있습니다. 제한된 SDK(Restricted SDK)를 설치하면 에어브릿지 SDK가 GAID, IDFA 같은 디바이스ID를 수집하지 않습니다.

아래 방법에 따라 제한된 SDK를 설치해 주세요.

<Tabs>
  <Tab title="SwiftPackageManager">
    1. Xcode에서 \[File]>\[Add Packages...]를 클릭합니다.

    2. 검색창에 아래 주소를 입력하고 \[Add Package]를 클릭합니다.
       * [https://github.com/ab180/airbridge-ios-sdk-restricted-deployment](https://github.com/ab180/airbridge-ios-sdk-restricted-deployment)

    3. \[Add Package]를 계속해서 클릭합니다.

    4. Xcode의 \[Package Dependencies]에서 Airbridge가 추가된 것을 확인할 수 있습니다.

    5. SDK의 의존성에 해당하는 Framework를 프로젝트에 추가합니다. \[Xcode]>\[프로젝트 파일]>\[General]>\[Frameworks, Libraries, and Embedded Content]에서 ‘+’를 클릭합니다.

    6. 아래 Framework를 모두 추가합니다. 추가한 Framework의 Embed를 Do not Embed로 설정합니다. 그리고 \[Xcode]>\[프로젝트 파일]>\[Build Phase]>\[Link Binary With Libraries]에서 Status를 Optional로 설정합니다.

    | Framework               | 설명                                            |
    | ----------------------- | --------------------------------------------- |
    | CoreTelephony.framework | 통신사 정보를 수집하는데 사용합니다.                          |
    | StoreKit.framework      | SKAdNetwork 정보를 수집하는데 사용합니다.                  |
    | AdServices.framework    | Apple Ads의 어트리뷰션 정보를 수집하는데 사용합니다. (iOS 14.3+) |
    | WebKit.framework        | Web SDK와 연동하여 이벤트를 수집하는데 사용합니다.               |
  </Tab>

  <Tab title="CocoaPods">
    <Danger>
      **주의하세요**

      \[Xcode]>\[YOUR\_PROJECT]>\[Build Settings]>\[User Script Sandboxing]을 No로 설정한 후에 iOS SDK를 설치해야 합니다. 자세한 내용은 [CocoaPods 문서](https://github.com/CocoaPods/CocoaPods/issues/11946)를 참고해 주세요.
    </Danger>

    1. `brew install cocoapods`로 CocoaPods를 설치합니다.
    2. `pod init`로 Podfile을 생성합니다.
    3. Podfile에 아래 코드로 SDK를 의존성으로 추가합니다. 그리고 아래 링크에서 최신버전을 확인하고 `$HERE_LATEST_VERSION` 에 입력하세요.
       * SDK 버전 목록: [링크](/ko/developers/release-note-ios-sdk)

    ```ruby Podfile lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    target '[Project Name]' do
        ...
        # Replace $HERE_LATEST_VERSION with latest version
        # - Versions: https://help.airbridge.io/developers/release-note-ios-sdk
        # - Example: pod 'airbridge-ios-sdk-restricted', '4.X.X'
        pod 'airbridge-ios-sdk-restricted', '$HERE_LATEST_VERSION'
        ...
    end
    ```

    4. `pod install --repo-update`를 입력하면 설치가 진행됩니다
    5. `YOUR_PROJECT.xcworkspace`를 실행하면 에어브릿지 iOS SDK가 정상적으로 설치된 것을 확인할 수 있습니다.
  </Tab>

  <Tab title="Tuist">
    <Danger>
      **주의하세요**

      Tuist의 [Tuist's XcodeProj-based integration](https://docs.tuist.dev/en/guides/develop/projects/dependencies#tuists-xcodeprojbased-integration) 방식으로는 에어브릿지 iOS SDK를 설치할 수 없습니다. 반드시 [Xcode's default integration](https://docs.tuist.dev/en/guides/develop/projects/dependencies#xcodes-default-integration) 방식으로 설치해 주세요.
    </Danger>

    1. `tuist edit` 명령어를 실행합니다.
    2. `project.packages`에 `remote`를 추가합니다. SDK를 `project.targets[...].target.dependencies`에 `package`로, 의존성 Framework를 `sdk`로 추가합니다. 그리고 아래 링크에서 최신버전을 확인하고 `$HERE_LATEST_VERSION` 에 입력하세요.
       * SDK 버전 목록: [링크](/ko/developers/release-note-ios-sdk)

    * 의존성 Framework 목록

    | Framework               | 설명                                            |
    | ----------------------- | --------------------------------------------- |
    | CoreTelephony.framework | 통신사 정보를 수집하는데 사용합니다.                          |
    | StoreKit.framework      | SKAdNetwork 정보를 수집하는데 사용합니다.                  |
    | AdServices.framework    | Apple Ads의 어트리뷰션 정보를 수집하는데 사용합니다. (iOS 14.3+) |
    | WebKit.framework        | Web SDK와 연동하여 이벤트를 수집하는데 사용합니다.               |

    ```swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    import ProjectDescription

    let project = Project(
        packages: [
            .remote(
                url: "https://github.com/ab180/airbridge-ios-sdk-restricted-deployment",
                // Replace $HERE_LATEST_VERSION with latest version
                // - Versions: https://help.airbridge.io/developers/release-note-ios-sdk
                // - Example: requirement: .exact(from: "4.X.X")
                requirement: .exact(from: "$HERE_LATEST_VERSION")
            ),
            ...
        ],
        targets: [
            .target(
                dependencies: [
                    .package(product: "Airbridge", type: .runtime),
                    .sdk(name: "AdServices", type: .framework, status: .optional),
                    .sdk(name: "CoreTelephony", type: .framework, status: .optional),
                    .sdk(name: "StoreKit", type: .framework, status: .optional),
                    .sdk(name: "WebKit", type: .framework, status: .optional),
                    ...
                ]
            ),
            ...
        ],
        ...
    )
    ```

    3. `tuist generate` 명령어를 실행합니다.
    4. Xcode의 Package Dependencies에 Airbridge가 추가됩니다.
  </Tab>

  <Tab title="직접 설치">
    1. 아래 링크에서 에어브릿지 iOS SDK를 다운로드합니다.
       * [https://sdk-download.airbridge.io/airbridge-ios-sdk-restricted/latest/Airbridge.zip](https://sdk-download.airbridge.io/airbridge-ios-sdk-restricted/latest/Airbridge.zip)

    2. Airbridge.xcframework를 프로젝트에 추가합니다. \[Xcode]>\[프로젝트 파일]>\[General]>\[Frameworks, Libraries, and Embedded Content]에서 ‘+’를 클릭합니다.

    3. \[Add Other...]에서 ‘Add Files...’를 클릭하고 Airbridge.xcframework를 선택합니다.

    4. Airbridge.xcframework의 Embed를 Embed & Sign로 설정합니다.

    5. SDK의 의존성에 해당하는 Framework를 프로젝트에 추가합니다. \[Xcode]>\[프로젝트 파일]>\[General]>\[Frameworks, Libraries, and Embedded Content]에서 ‘+’를 클릭합니다.

    6. 아래 Framework를 모두 추가합니다. 추가한 Framework의 Embed를 Do not Embed로 설정합니다. 그리고 \[Xcode]>\[프로젝트 파일]>\[Build Phase]>\[Link Binary With Libraries]에서 Status를 Optional로 설정합니다.

    | Framework               | 설명                                            |
    | ----------------------- | --------------------------------------------- |
    | CoreTelephony.framework | 통신사 정보를 수집하는데 사용합니다.                          |
    | StoreKit.framework      | SKAdNetwork 정보를 수집하는데 사용합니다.                  |
    | AdServices.framework    | Apple Ads의 어트리뷰션 정보를 수집하는데 사용합니다. (iOS 14.3+) |
    | WebKit.framework        | Web SDK와 연동하여 이벤트를 수집하는데 사용합니다.               |
  </Tab>
</Tabs>

### SDK 초기화하기

시스템 방식에 따라 SDK 초기화 방법이 다릅니다. SceneDelegate Lifecycle 또는 AppDelegate Lifecycle은 AppDelegate를 참고해 주세요. SwiftUI Lifecycle는 SwiftUI를 참고해 주세요.

YOUR\_APP\_NAME과 YOUR\_APP\_SDK\_TOKEN은 에어브릿지 대시보드의 \[설정]>\[토큰 관리]에서 확인할 수 있습니다.

<Tabs>
  <Tab title="AppDelegate (Swift)">
    `AppDelegate`의 `application(_:didFinishLaunchingWithOptions:)` 가장 위에서 `Airbridge.initializeSDK` 함수를 호출합니다.

    ```swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    import UIKit
    import Airbridge

    @main
    class AppDelegate: UIResponder, UIApplicationDelegate {
        func application(
            _ application: UIApplication,
            didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
        ) -> Bool {
            let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
                .build()
            Airbridge.initializeSDK(option: option)
            return true
        }
    }
    ```

    <Danger>
      **주의하세요**

      `Airbridge.initializeSDK` 함수를 `AppDelegate` 의 `application(_:didFinishLaunchingWithOptions:)` 시점에 호출해야 올바르게 동작합니다.
    </Danger>
  </Tab>

  <Tab title="AppDelegate (Objective-C)">
    AppDelegate의 `application:didFinishLaunchingWithOptions:` 가장 위에서 `Airbridge.initializeSDK` 함수를 호출합니다.

    ```objective-c lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    #import "AppDelegate.h"
    #import <Airbridge/Airbridge.h>

    @interface AppDelegate ()

    @end

    @implementation AppDelegate

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                       token:@"YOUR_APP_SDK_TOKEN"];
        AirbridgeOption* option = [optionBuilder build];
        [Airbridge initializeSDKWithOption:option];
        return YES;
    }

    @end
    ```

    <Danger>
      **주의하세요**

      `Airbridge.initializeSDK` 함수를 `AppDelegate` 의 `application(_:didFinishLaunchingWithOptions:)` 시점에 호출해야 올바르게 동작합니다.
    </Danger>
  </Tab>

  <Tab title="SwiftUI">
    `init` 가장 위에서 `Airbridge.initializeSDK` 함수를 호출합니다.

    ```swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    import SwiftUI
    import Airbridge

    @main
    struct ExampleApp: App {
        init() {
            let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
                .build()
            Airbridge.initializeSDK(option: option)
        }
        
        var body: some Scene {
            WindowGroup {
                ContentView()
            }
        }
    }
    ```

    <Danger>
      **주의하세요**

      `Airbridge.initializeSDK` 함수를 `App` 의 `init` 시점에 호출해야 올바르게 동작합니다.
    </Danger>

    <Danger>
      **주의하세요**

      SwiftUI Lifecycle 방식은 리퍼러 URL(ReferrerURL)을 제공하지 않아 [오가닉 리퍼러 어트리뷰션](/ko/guides/organic-referrer-attribution)을 사용할 수 없습니다. UIApplicationDelegateAdaptor를 활용해도 SwiftUI Lifecycle 방식에서는 오가닉 리퍼러 어트리뷰션을 사용할 수 없습니다.
    </Danger>
  </Tab>
</Tabs>

### ATT 프롬프트 제공하기

<Info>
  **알립니다**

  개인정보보호 정책 준수를 위해 필요한 기능은 법률 자문사와 함께 검토해야 합니다.
</Info>

iOS 환경에서는 식별자로 [앱 추적 투명성(AppTrackingTransparency, ATT)](https://developer.apple.com/app-store/user-privacy-and-data-use/) 프롬프트에서 정보 수집에 동의한 유저의 [IDFA](https://developer.apple.com/documentation/adsupport/asidentifiermanager/advertisingidentifier)만 수집할 수 있습니다.

유저가 추적에 동의하기 전에는 이벤트 수집을 지연해야 합니다. 유저가 ATT 프롬프트에서 정보 수집에 동의하기 전에 앱 설치 이벤트를 수집하면 이벤트에 식별자가 없어 성과 측정이 어렵습니다. 식별자를 수집하기 위한 충분한 이벤트 수집 지연 시간을 설정하는 것을 권장합니다.

1. ATT 프롬프트에 사용하는 문구를 준비합니다.
2. 준비한 문구를 `Info.plist` 파일의 `NSUserTrackingUsageDescription` 키에 입력합니다.

<Tabs>
  <Tab title="Xcode">
    1) Xcode > YOUR\_PROJECT > Info > Custom iOS Target Properties로 이동해주세요.
    2) Key의 항목들에 마우스를 가져가면 표시되는 + 버튼을 누르고 `Privacy - Tracking Usage Description` 를 입력해 주세요.
    3) Value에 표시할 문구를 입력해 주세요.
  </Tab>

  <Tab title="Tuist">
    1. tuist edit 명령어를 실행해주세요.
    2. `project.targets[...].infoPlist` 의 `.extendingDefault` 에 키로 `NSUserTrackingUsageDescription` 를, 밸류로 문구를 입력해주세요.

    ```swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    import ProjectDescription

    let project = Project(
        targets: [
            .target(
                infoPlist: .extendingDefault(
                    with: [
                        "NSUserTrackingUsageDescription": "YOUR_DESCRIPTION",
                        ...
                    ]
                ),
                ...
            ),
            ...
        ]
        ...
    )
    ```
  </Tab>
</Tabs>

3. ATT 프롬프트를 제공하는 시점을 결정합니다.

<AccordionGroup>
  <Accordion title="원하는 시점에 ATT 프롬프트 제공하기">
    ATT 프롬프트를 제공하는 시점에 `ATTrackingManager.requestTrackingAuthorization` 함수를 호출합니다.

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import AppTrackingTransparency
      ...
      ATTrackingManager.requestTrackingAuthorization { _ in }
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <AppTrackingTransparency/AppTrackingTransparency.h>
      ...
      [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {}];
      ```
    </CodeGroup>

    <Danger>
      **주의하세요**

      `ATTrackingManager.requestTrackingAuthorization` 함수는 호출한 앱이 Active 상태가 아니면 ATT 프롬프트를 제공하지 않습니다.
    </Danger>
  </Accordion>

  <Accordion title="앱을 실행하면 ATT 프롬프트 제공하기">
    앱이 실행되는 순간에 바로 ATT 프롬프트를 제공할 수 있습니다.

    <CodeGroup>
      ```swift AppDelegate (Swift) lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import UIKit
      import Airbridge
      import AppTrackingTransparency

      @main
      class AppDelegate: UIResponder, UIApplicationDelegate {
          var observer: Any?

          func application(
              _ application: UIApplication,
              didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
          ) -> Bool {
              let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
                  .build()
              Airbridge.initializeSDK(option: option)

              observer = NotificationCenter.default.addObserver(
                  forName: UIApplication.didBecomeActiveNotification,
                  object: nil,
                  queue: nil
              ) { [weak self] _ in
                  if #available(iOS 14, *) {
                      ATTrackingManager.requestTrackingAuthorization { _ in }
                  }
                  if let observer = self?.observer {
                      NotificationCenter.default.removeObserver(observer)
                  }
              }

              return true
          }
      }
      ```

      ```objective-c AppDelegate (Objective-C) lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import "AppDelegate.h"
      #import <Airbridge/Airbridge.h>
      #import <AppTrackingTransparency/AppTrackingTransparency.h>

      @interface AppDelegate ()

      @end

      @implementation AppDelegate {
          id observer;
      }

      - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
          AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                         token:@"YOUR_APP_SDK_TOKEN"];
          AirbridgeOption* option = [optionBuilder build];
          [Airbridge initializeSDKWithOption:option];
          __weak typeof(self) weakSelf = self;
          observer = [NSNotificationCenter.defaultCenter addObserverForName:UIApplicationDidBecomeActiveNotification
                                                                  object:nil
                                                                      queue:nil
                                                              usingBlock:^(NSNotification * _Nonnull notification) {
              if (@available(iOS 14, *)) {
                  [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {}];
              }
              if (weakSelf != nil && weakSelf->observer != nil) {
                  [NSNotificationCenter.defaultCenter removeObserver:observer];
              }
          }];
          return YES;
      }

      @end
      ```

      ```swift SwiftUI lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import SwiftUI
      import Airbridge
      import AppTrackingTransparency

      @main
      struct ExampleApp: App {
          init() {
              let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
                  .build()
              Airbridge.initializeSDK(option: option)

              var observer: Any?
              observer = NotificationCenter.default.addObserver(
                  forName: UIApplication.didBecomeActiveNotification,
                  object: nil,
                  queue: nil
              ) { _ in
                  if #available(iOS 14, *) {
                      ATTrackingManager.requestTrackingAuthorization { _ in }
                  }
                  if let observer {
                      NotificationCenter.default.removeObserver(observer)
                  }
              }
          }
          
          var body: some Scene {
              WindowGroup {
                  ContentView()
              }
          }
      }
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

4. 에어브릿지 iOS SDK는 설치 이벤트가 수집되지 않으면 앱이 실행될 때마다 유저가 추적에 동의하기 전까지 30초 동안 설치 이벤트 수집을 지연합니다. 유저가 추적 동의 여부를 결정하기 전에 앱을 종료하면 설치 이벤트를 수집하지 않고 다음 앱 실행에 다시 시도합니다.

`setAutoDetermineTrackingAuthorizationTimeout` 함수로 설치 이벤트 수집 지연 시간을 더 길게 설정할 수 있습니다. `setAutoDetermineTrackingAuthorizationTimeout` 함수의 기본 설정은 30초입니다. 최대 3600초(1시간)까지 설정할 수 있습니다.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME",
                                      token: "YOUR_APP_SDK_TOKEN")
      .setAutoDetermineTrackingAuthorizationTimeout(second: 30)
      .build()
  Airbridge.initializeSDK(option: option)
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>
  ...
  AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                 token:@"YOUR_APP_SDK_TOKEN"];
  [optionBuilder setAutoDetermineTrackingAuthorizationTimeoutWithSecond:30];
  AirbridgeOption* option = [optionBuilder build];
  [Airbridge initializeSDKWithOption:option];
  ```
</CodeGroup>

<Danger>
  **주의하세요**

  앱 설치 이벤트의 수집을 지연하는 시간을 충분히 설정해야 합니다. 유저가 ATT 프롬프트에서 정보 수집에 동의하기 전에 앱 설치 이벤트를 수집하면 IDFA가 함께 수집되지 않습니다.
</Danger>

### 옵트인(Opt-In) 설정하기

<Info>
  **알립니다**

  필수 설정 기능이 아닙니다. 필요한 경우에만 설정해 주세요.
</Info>

옵트인(Opt-In)은 유저가 동의하기 전에 유저 정보를 사용하지 않는 정책입니다.

`setAutoStartTrackingEnabled` 함수를 false로 설정한 후에 이벤트를 수집할 수 있는 시점에 `startTracking` 함수를 호출합니다. `startTracking` 함수가 호출된 시점부터 이벤트를 수집합니다.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
      .setAutoStartTrackingEnabled(false)
      .build()
  Airbridge.initializeSDK(option: option)
  ...
  Airbridge.startTracking()
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>
  ...
  AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                 token:@"YOUR_APP_SDK_TOKEN"];
  [optionBuilder setAutoStartTrackingEnabled:NO];
  AirbridgeOption* option = [optionBuilder build];
  [Airbridge initializeSDKWithOption:option];
  ...
  [Airbridge startTracking];
  ```
</CodeGroup>

### 옵트아웃(Opt-Out) 설정하기

<Info>
  **알립니다**

  필수 설정 기능이 아닙니다. 필요한 경우에만 설정해 주세요.
</Info>

옵트아웃(Opt-Out)은 유저가 거부하기 전에 유저 정보를 사용하는 정책입니다.

setAutoStartTrackingEnabled 설정을 true로 설정한 후에 이벤트를 수집할 수 없는 시점에 stopTracking 함수를 호출합니다. stopTracking 함수가 호출된 시점부터 이벤트를 수집하지 않습니다.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
      .setAutoStartTrackingEnabled(true)
      .build()
  Airbridge.initializeSDK(option: option)
  ...
  Airbridge.stopTracking()
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>
  ...
  AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                 token:@"YOUR_APP_SDK_TOKEN"];
  [optionBuilder setAutoStartTrackingEnabled:YES];
  AirbridgeOption* option = [optionBuilder build];
  [Airbridge initializeSDKWithOption:option];
  ...
  [Airbridge stopTracking];
  ```
</CodeGroup>

### SDK 시그니처 설정하기

<Info>
  **알립니다**

  필수 설정 기능이 아닙니다. 필요한 경우에만 설정해 주세요.
</Info>

SDK 시그니처(SDK Signature)로 SDK 스푸핑(SDK Spoofing)을 방지해 정확성과 안전성이 검증된 이벤트만 광고 성과 측정에 사용할 수 있습니다.

SDK 시그니처 설정에 SDK 시그니처 보안 정보가 필요합니다. SDK 시그니처 보안 정보에는 시크릿 ID와 시크릿이 있습니다. 필요한 SDK 시그니처 보안 정보는 에어브릿지 대시보드에서 확인할 수 있습니다. SDK 시그니처 보안 정보에 대한 자세한 내용은 [에어브릿지 가이드](/ko/guides/sdk-signature)를 참고해 주세요.

SDK 초기화 코드 위에서 `setSDKSignature` 함수를 호출해 SDK 시그니처를 설정할 수 있습니다.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
      .setSDKSignature(
          id: "YOUR_SDK_SIGNATURE_SECRET_ID",
          secret: "YOUR_SDK_SIGNATURE_SECRET"
      )
      .build()
  Airbridge.initializeSDK(option: option)
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>
  ...
  AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                 token:@"YOUR_APP_SDK_TOKEN"];
  [optionBuilder setSDKSignatureWithId:@"YOUR_SDK_SIGNATURE_SECRET_ID"
                                secret:@"YOUR_SDK_SIGNATURE_SECRET"];
  AirbridgeOption* option = [optionBuilder build];
  [Airbridge initializeSDKWithOption:option];
  ```
</CodeGroup>

SDK 설정에 필요한 정보는 아래와 같습니다.

* YOUR\_APP\_NAME: 에어브릿지 앱 이름. 에어브릿지 대시보드의 \[설정]>\[토큰 관리]에서 확인할 수 있습니다.
* YOUR\_APP\_SDK\_TOKEN: 안드로이드 SDK 토큰. 에어브릿지 대시보드의 \[설정]>\[토큰 관리]에서 확인할 수 있습니다.
* YOUR\_SDK\_SIGNATURE\_SECRET\_ID: 시크릿 ID. 에어브릿지 대시보드 \[규칙 관리]>\[광고사기 검증 규칙]>\[SDK 시그니처]에서 확인할 수 있습니다.
* YOUR\_SDK\_SIGNATURE\_SECRET: 시크릿. 에어브릿지 대시보드 \[규칙 관리]>\[광고사기 검증 규칙]>\[SDK 시그니처]에서 확인할 수 있습니다.

## 딥링크

딥링크를 설정하면 트래킹 링크가 있는 광고를 클릭한 유저를 원하는 앱의 특정 페이지로 이동시킬 수 있습니다. 또한 트래킹 링크로 수집된 정보를 바탕으로 딥링크를 통해서 발생한 성과를 에어브릿지에서 확인할 수 있습니다.

* [트래킹 링크 이해하기 (유저 가이드)](/ko/guides/understanding-tracking-link)
* [딥링크 이해하기 (유저 가이드)](/ko/guides/understanding-deep-link)

### 에어브릿지의 딥링크 작동 방식

에어브릿지는 트래킹 링크가 열릴 때, 트래킹 링크에 설정된 스킴 딥링크를 유저의 환경에 따라 최적인 형태의 에어브릿지 딥링크(HTTP 딥링크 또는 스킴 딥링크)로 변환하여 유저를 앱으로 이동시킵니다. 그리고 에어브릿지 SDK가 에어브릿지 딥링크를 트래킹 링크에 설정된 스킴 딥링크로 다시 변환하여 앱에 전달합니다.

* 트래킹 링크에 설정된 스킴 딥링크 예시: `YOUR_SCHEME://product/12345`
* 에어브릿지 딥링크 예시
  * HTTP 딥링크 형태 1: `https://YOUR_APP_NAME.airbridge.io/~~~`
  * HTTP 딥링크 형태 2: `https://YOUR_APP_NAME.abr.ge/~~~`
  * 스킴 딥링크 형태: `YOUR_SCHEME://product/12345?airbridge_referrer=~~~`

앱이 설치된 상태에서 유저가 트래킹 링크를 열면 에어브릿지 딥링크로 앱이 열립니다. 그리고 에어브릿지 SDK는 해당 에어브릿지 딥링크를 트래킹 링크에 설정되어 있는 스킴 딥링크로 변환한 후에 이를 앱에 전달합니다.

앱이 설치되어 있지 않은 상태에서 유저가 트래킹 링크를 열면 SDK는 에어브릿지 딥링크를 저장합니다. 유저가 앱스토어 또는 웹 사이트로 이동하여 앱 설치 후 앱을 실행하면 에어브릿지 SDK는 저장한 에어브릿지 딥링크를 트래킹 링크에 설정된 스킴 딥링크로 변환한 후에 이를 앱에 전달합니다.

<Frame>
  <img src="https://mintcdn.com/airbridge-help-center/6CTRFgWYblklSTQJ/asset/image/deep-link-deferred-routing-diagram.png?fit=max&auto=format&n=6CTRFgWYblklSTQJ&q=85&s=feca42b0a16d964f5950eb31e0fe53cb" alt="에어브릿지 딥링크 간단구조" width="1500" height="506" data-path="asset/image/deep-link-deferred-routing-diagram.png" />
</Frame>

### 딥링크 설정하기

딥링크를 설정합니다. 에어브릿지 대시보드에서 설정한 정보와 유저가 이동하는 목적지로 사용되는 앱 페이지 주소가 필요합니다.

먼저 에어브릿지에 딥링크 정보를 등록합니다.

<Accordion title="에어브릿지에 딥링크 정보 등록하기">
  에어브릿지 대시보드의 \[트래킹링크]>\[딥링크]에 딥링크 정보를 등록해주세요.

  **iOS URI 스킴**

  딥링크에 사용할 스킴을 입력해주세요. 에어브릿지는 입력한 스킴을 사용하는 딥링크만 트래킹링크에 설정할 수 있고, 트래킹링크로 앱이 열릴 때 설정한 스킴 딥링크가 전달됩니다. 예: `scheme://`

  **iOS 앱 ID**

  [애플 개발자 대시보드](https://developer.apple.com/account/resources)의 앱의 \[Identifier]에서 `App ID Prefix` , `Bundle ID` 값을 가져와서 `App ID Prefix` + . + `Bundle ID` 형식으로 입력해주세요. 예: `9JA89QQLNQ.com.apple.wwdc`

  <Danger>
    **주의하세요**

    실제 출시 앱과 개발용 앱의 iOS URI 스킴과 iOS 앱 ID를 다르게 등록해야 유저를 정상적으로 이동 시킬 수 있습니다.
  </Danger>
</Accordion>

에어브릿지에 딥링크 정보를 등록한 후에 앱에 딥링크를 설정해야 합니다. 앱에서 딥링크를 위해 필요한 개발은 아래와 같습니다.

* 에어브릿지 딥링크로 앱이 실행되도록 설정합니다.
* 에어브릿지 딥링크로 유저를 이동시킵니다.

아래 내용을 참고해 주세요.

<AccordionGroup>
  <Accordion title="에어브릿지 딥링크로 앱이 실행되도록 설정하기">
    유저가 트래킹 링크를 클릭한 후에 앱이 에어브릿지 딥링크로 실행되도록 설정합니다.

    **스킴 딥링크 앱 설정**

    1. Xcode에서 \[YOUR\_PROJECT]>\[Info]>\[URL Types]로 이동합니다.
    2. '+'를 클릭한 후에 URL Schemes에 대시보드에서 입력한 iOS URI 스킴을 입력합니다.

    <Danger>
      **주의하세요**

      `://`를 제외한 iOS URL 스킴을 입력해야 합니다.
    </Danger>

    **유니버셜 링크 앱 설정**

    1. Xcode에서 \[YOUR\_PROJECT]>\[Signing & Capabilities]로 이동합니다.
    2. '+ Capability'를 클릭하면 Associated Domains를 추가할 수 있습니다.
    3. Associated Domains에 `applinks:YOUR_APP_NAME.airbridge.io`와 `applinks:YOUR_APP_NAME.abr.ge` 를 추가합니다. (`YOUR_APP_NAME` 은 에어브릿지 대시보드의 \[설정]>\[토큰 관리]에서 확인할 수 있습니다.)

    <Danger>
      **주의하세요**

      [Password AutoFill](https://developer.apple.com/documentation/security/password-autofill) 기능을 사용하고 있거나 사용할 계획이 있다면 Webcredentials 도메인을 반드시 추가해야 합니다. Password AutoFill 기능으로 저장된 암호의 도메인이 `airbridge.io` 또는 `abr.ge`로 보이는 현상이 앱을 사용하는 유저에게 발생할 수 있습니다.
    </Danger>
  </Accordion>

  <Accordion title="에어브릿지 딥링크로 유저를 이동시키기">
    앱이 딥링크로 열릴 때, `trackDeeplink` 함수를 호출해 SDK가 딥링크 오픈 이벤트를 수집할 수 있게 해주세요. 그리고 `handleDeeplink` 함수를 호출해 에어브릿지 딥링크를 원래 트래킹링크에 설정된 스킴 딥링크로 변환해주세요. 그리고 유저를 의도된 화면으로 이동시켜주세요.

    앱이 에어브릿지 딥링크로 열리면 `isAirbridgeDeeplink` 는 `true` 가 되고, 콜백의 `uri` 에는 설정된 스킴 딥링크가 전달됩니다. 앱이 다른 딥링크로 열리면 `isAirbridgeDeeplink` 는 `false` 가 되고, 콜백은 호출되지 않습니다. 이를 활용하면 에어브릿지 딥링크를 별도로 처리할 수 있습니다.

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      /** when app is opened with deeplink */

      // track deeplink
      Airbridge.trackDeeplink(url: url)
      // handle deeplink
      var isAirbridgeDeeplink = Airbridge.handleDeeplink(url: url) { url in
          // when app is opened with airbridge deeplink
          // show proper content using url (YOUR_SCHEME://...)
          handleAirbridgeDeeplink(url: url)
      }
      if isAirbridgeDeeplink { return }
      // when app is opened with other deeplink
      // use existing logic as it is
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      /** when app is opened with deeplink */

      // track deeplink
      [Airbridge trackDeeplinkWithUrl:url];
      // handle deeplink
      BOOL isAirbridgeDeeplink = [Airbridge handleDeeplinkWithUrl:url onSuccess:^(NSURL* url) {
          // when app is opened with airbridge deeplink
          // show proper content using url (YOUR_SCHEME://...)
      }];
      if (isAirbridgeDeeplink) { return; }
      // when app is opened with other deeplink
      // use existing logic as it is
      ```
    </CodeGroup>

    앱이 딥링크로 열릴 때마다 `trackDeeplink` 함수와 `handleDeeplink` 함수를 호출하여 딥링크 오픈 이벤트를 수집하고 유저를 의도한 화면으로 이동시켜주세요.

    SceneDelegate와 AppDelegate가 모두 있다면 SceneDelegate 클래스에, AppDelegate만 있다면 AppDelegate 클래스에, 모두 없고 SwiftUI를 사용한다면 App 클래스에 아래와 같은 콜백 설정이 필요합니다.

    <Tabs>
      <Tab title="SceneDelegate (Swift)">
        앱이 딥링크로 열릴 때 SceneDelegate 클래스에서 호출되는 콜백은 아래와 같습니다.

        | 앱이 딥링크로 열리는 상황                          | 콜백                             |
        | --------------------------------------- | ------------------------------ |
        | 앱이 꺼진 상태에서 `URL 스킴` 또는 `유니버셜 링크` 로 열릴 때 | `scene:willConnectTo:options:` |
        | 앱이 백그라운드에 있는 상태에서 `URL 스킴` 으로 열릴 때      | `scene:openURLContexts:`       |
        | 앱이 백그라운드에 있는 상태에서 `유니버셜 링크` 로 열릴 때      | `scene:continue:`              |

        1. 앱이 에어브릿지 딥링크로 열렸을 때 유저를 이동시키는 함수를 구현하세요. 이는 유저를 의도한 화면으로 이동키시기 위해 각각의 콜백에 추가해야하는 함수입니다.

        ```swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        import UIKit
        import Airbridge
        ...
        class SceneDelegate: UIResponder, UIWindowSceneDelegate {
            ...
            // when app is opened with airbridge deeplink
            func handleAirbridgeDeeplink(url: URL) {
                // show proper content using url (YOUR_SCHEME://...)
            }
            ...
        }
        ```

        2. `scene:willConnectTo:options:` 콜백을 설정하세요. `trackDeeplink` 함수와 `handleDeeplink` 함수를 호출하여 딥링크 오픈 이벤트를 수집하고 위에서 구현한 함수를 호출하여 유저를 이동시키세요.

        ```swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        import UIKit
        import Airbridge
        ...
        class SceneDelegate: UIResponder, UIWindowSceneDelegate {
            ...
            // when terminated app is opened with scheme deeplink or universal links
            func scene(
                _ scene: UIScene,
                willConnectTo session: UISceneSession,
                options connectionOptions: UIScene.ConnectionOptions
            ) {
                // track deeplink
                Airbridge.trackDeeplink(connectionOptions: connectionOptions)
                // handle deeplink

                var isAirbridgeDeeplink = Airbridge.handleDeeplink(connectionOptions: connectionOptions)
                    // when app is opened with airbridge deeplink
                    // show proper content using url (YOUR_SCHEME://...)
                    handleAirbridgeDeeplink(url: url)
                }
                
                if isAirbridgeDeeplink { return }
                // when app is opened with other deeplink
                // use existing logic as it is
            }
            ...
        }
        ```

        3. `scene:openURLContexts:` 콜백을 설정하세요. `trackDeeplink` 함수와 `handleDeeplink` 함수를 호출하여 딥링크 오픈 이벤트를 수집하고 위에서 구현한 함수를 호출하여 유저를 이동시키세요.

        ```swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        import UIKit
        import Airbridge
        ...
        class SceneDelegate: UIResponder, UIWindowSceneDelegate {
            ...
            // when backgrounded app is opened with scheme deeplink
            func scene(
                _ scene: UIScene,
                openURLContexts URLContexts: Set<UIOpenURLContext>
            ) {
                // track deeplink
                Airbridge.trackDeeplink(openURLContexts: openURLContexts)
                // handle deeplink

                var isAirbridgeDeeplink = Airbridge.handleDeeplink(openURLContexts: openURLContexts) { url in
                    // when app is opened with airbridge deeplink
                    // show proper content using url (YOUR_SCHEME://...)
                    handleAirbridgeDeeplink(url: url)
                }
                
                if isAirbridgeDeeplink { return }
                // when app is opened with other deeplink
                // use existing logic as it is
            }
            ...
        }
        ```

        4. `scene:continue:` 콜백을 설정하세요. `trackDeeplink` 함수와 `handleDeeplink` 함수를 호출하여 딥링크 오픈 이벤트를 수집하고 위에서 구현한 함수를 호출하여 유저를 이동시키세요.

        ```swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        import UIKit
        import Airbridge
        ...
        class SceneDelegate: UIResponder, UIWindowSceneDelegate {
            ...
            // when backgrounded app is opened with universal links
            func scene(
                _ scene: UIScene,
                continue userActivity: NSUserActivity
            ) {
                // track deeplink
                Airbridge.trackDeeplink(userActivity: userActivity)
                // handle deeplink
                var isAirbridgeDeeplink = Airbridge.handleDeeplink(userActivity: userActivity) { url in
                    // when app is opened with airbridge deeplink
                    // show proper content using url (YOUR_SCHEME://...)
                    handleAirbridgeDeeplink(url: url)
                }
                if isAirbridgeDeeplink { return }
                // when app is opened with other deeplink
                // use existing logic as it is
            }
            ...
        }
        ```
      </Tab>

      <Tab title="AppDelegate (Swift)">
        앱이 딥링크로 열릴 때 AppDelegate 클래스에서 호출되는 콜백은 아래와 같습니다.

        | 앱이 딥링크로 열리는 상황                          | 콜백                                         |
        | --------------------------------------- | ------------------------------------------ |
        | 앱이 꺼지거나 백그라운드에 있는 상태에서 `URL 스킴` 으로 열릴 때 | `application:open:options:`                |
        | 앱이 꺼지거나 백그라운드에 있는 상태에서 `유니버셜 링크` 로 열릴 때 | `application:continue:restorationHandler:` |

        1. 앱이 에어브릿지 딥링크로 열렸을 때 유저를 이동시키는 함수를 구현하세요. 이는 유저를 의도한 화면으로 이동키시기 위해 각각의 콜백에 추가해야하는 함수입니다.

        ```swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        import UIKit
        import Airbridge
        ...
        class AppDelegate: UIResponder, UIApplicationDelegate {
            ...
            // when app is opened with airbridge deeplink
            func handleAirbridgeDeeplink(url: URL) {
                // show proper content using url (YOUR_SCHEME://...)
            }
            ...
        }
        ```

        2. `application:open:options:` 콜백을 설정하세요. `trackDeeplink` 함수와 `handleDeeplink` 함수를 호출하여 딥링크 오픈 이벤트를 수집하고 위에서 구현한 함수를 호출하여 유저를 이동시키세요.

        ```swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        import UIKit
        import Airbridge
        ...
        class AppDelegate: UIResponder, UIApplicationDelegate {
            ...
            // when app is opened with scheme deeplink
            func application(
                _ app: UIApplication,
                open url: URL,
                options: [UIApplication.OpenURLOptionsKey : Any] = [:]
            ) -> Bool {
                // track deeplink
                Airbridge.trackDeeplink(url: url)
                // handle deeplink
                var isAirbridgeDeeplink = Airbridge.handleDeeplink(url: url) { url in
                    // when app is opened with airbridge deeplink
                    // show proper content using url (YOUR_SCHEME://...)
                    handleAirbridgeDeeplink(url: url)
                }
                
                if isAirbridgeDeeplink { return true }
                // when app is opened with other deeplink
                // use existing logic as it is
                return isAirbridgeDeeplink
            }
            ...
        }
        ```

        3. `application:continue:restorationHandler:` 콜백을 설정하세요. `trackDeeplink` 함수와 `handleDeeplink` 함수를 호출하여 딥링크 오픈 이벤트를 수집하고 위에서 구현한 함수를 호출하여 유저를 이동시키세요.

        ```swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        import UIKit
        import Airbridge
        ...
        class AppDelegate: UIResponder, UIApplicationDelegate {
            ...
            // when app is opened with universal links
            func application(
                _ application: UIApplication,
                continue userActivity: NSUserActivity,
                restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
            ) -> Bool {
                // track deeplink
                Airbridge.trackDeeplink(userActivity: userActivity)
                // handle deeplink
                var isAirbridgeDeeplink = Airbridge.handleDeeplink(userActivity: userActivity) { url in
                    // when app is opened with airbridge deeplink
                    // show proper content using url (YOUR_SCHEME://...)
                    handleAirbridgeDeeplink(url: url)
                }
                if isAirbridgeDeeplink { return true }
                // when app is opened with other deeplink
                // use existing logic as it is
                return isAirbridgeDeeplink
            }
            ...
        }
        ```
      </Tab>

      <Tab title="SwiftUI (Swift)">
        앱이 딥링크로 열릴 때 App 클래스에서 호출되는 콜백은 아래와 같습니다.

        | 앱이 딥링크로 열리는 상황                                          | 콜백          |
        | ------------------------------------------------------- | ----------- |
        | 앱이 꺼지거나 백그라운드에 있는 상태에서 `URL Scheme` 또는 `유니버셜 링크` 로 열릴 때 | `onOpenURL` |

        1. `onOpenURL` 콜백을 설정하세요. `trackDeeplink` 함수와 `handleDeeplink` 함수를 호출하여 딥링크 오픈 이벤트를 수집하고 위에서 구현한 함수를 호출하여 유저를 이동시키세요.

        ```swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        import SwiftUI
        import Airbridge

        @main
        struct ActualApp: App {
            var body: some Scene {
                WindowGroup {
                    ContentView()
                        // when app is opened with scheme deeplink or universal links
                        .onOpenURL { url in
                            // track deeplink
                            Airbridge.trackDeeplink(url: url)
                            // handle deeplink
                            var isAirbridgeDeeplink = Airbridge.handleDeeplink(url: url) { url in
                                // when app is opened with airbridge deeplink
                                // show proper content using url (YOUR_SCHEME://...)
                            }
                            if isAirbridgeDeeplink { return }
                            // when app is opened with other deeplink
                            // use existing logic as it is
                        }
                }
            }
        }
        ```
      </Tab>

      <Tab title="SceneDelegate (Objective-C)">
        앱이 딥링크로 열릴 때 SceneDelegate 클래스에서 호출되는 콜백은 아래와 같습니다.

        | 앱이 딥링크로 열리는 상황                          | 콜백                                    |
        | --------------------------------------- | ------------------------------------- |
        | 앱이 꺼진 상태에서 `URL 스킴` 또는 `유니버셜 링크` 로 열릴 때 | `scene:willConnectToSession:options:` |
        | 앱이 백그라운드에 있는 상태에서 `URL 스킴` 으로 열릴 때      | `scene:openURLContexts:`              |
        | 앱이 백그라운드에 있는 상태에서 `유니버셜 링크` 로 열릴 때      | `scene:continueUserActivity:`         |

        1. 앱이 에어브릿지 딥링크로 열렸을 때 유저를 이동시키는 함수를 구현하세요. 이는 유저를 의도한 화면으로 이동키시기 위해 각각의 콜백에 추가해야하는 함수입니다.

        ```objective-c lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        #import "SceneDelegate.h"
        #import <Airbridge/Airbridge.h>

        @interface SceneDelegate ()

        @end

        @implementation SceneDelegate
        ...
        // when app is opened with airbridge deeplink
        - (void)handleAirbridgeDeeplink:(NSURL *)url {
            // show proper content using url (YOUR_SCHEME://...)
        }
        ...
        @end
        ```

        2. `scene:willConnectToSession:options:` 콜백을 설정하세요. `trackDeeplink` 함수와 `handleDeeplink` 함수를 호출하여 딥링크 오픈 이벤트를 수집하고 위에서 구현한 함수를 호출하여 유저를 이동시키세요.

        ```objective-c lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        #import "SceneDelegate.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 {
            // track deeplink
            [Airbridge trackDeeplinkWithConnectionOptions:connectionOptions];
            // handle deeplink
            BOOL isAirbridgeDeeplink = [Airbridge handleDeeplinkWithConnectionOptions:connectionOptions onSuccess:^(NSURL* url) {
                // when app is opened with airbridge deeplink
                // show proper content using url (YOUR_SCHEME://...)
                [self handleAirbridgeDeeplink:url];
            }];
            if (isAirbridgeDeeplink) { return; }
            // when app is opened with other deeplink
            // use existing logic as it is
        }
        ...
        @end
        ```

        3. `scene:openURLContexts:` 콜백을 설정하세요. `trackDeeplink` 함수와 `handleDeeplink` 함수를 호출하여 딥링크 오픈 이벤트를 수집하고 위에서 구현한 함수를 호출하여 유저를 이동시키세요.

        ```objective-c lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        #import "SceneDelegate.h"
        #import <Airbridge/Airbridge.h>

        @interface SceneDelegate ()

        @end

        @implementation SceneDelegate
        ...
        // when backgrounded app is opened with scheme deeplink
        - (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts {
            // track deeplink
            [Airbridge trackDeeplinkWithOpenURLContexts:URLContexts];
            // handle deeplink
            BOOL isAirbridgeDeeplink = [Airbridge handleDeeplinkWithOpenURLContexts:URLContexts onSuccess:^(NSURL* url) {
                // when app is opened with airbridge deeplink
                // show proper content using url (YOUR_SCHEME://...)
                [self handleAirbridgeDeeplink:url];
            }];
            if (isAirbridgeDeeplink) { return; }
            // when app is opened with other deeplink
            // use existing logic as it is
        }
        ...
        @end
        ```

        4. `scene:continueUserActivity:` 콜백을 설정하세요. `trackDeeplink` 함수와 `handleDeeplink` 함수를 호출하여 딥링크 오픈 이벤트를 수집하고 위에서 구현한 함수를 호출하여 유저를 이동시키세요.

        ```objective-c lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        #import "SceneDelegate.h"
        #import <Airbridge/Airbridge.h>

        @interface SceneDelegate ()

        @end

        @implementation SceneDelegate
        ...
        // when backgrounded app is opened with universal links
        - (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity {
            // track deeplink
            [Airbridge trackDeeplinkWithUserActivity:userActivity];
            // handle deeplink
            BOOL isAirbridgeDeeplink = [Airbridge handleDeeplinkWithUserActivity:userActivity onSuccess:^(NSURL* url) {
                // when app is opened with airbridge deeplink
                // show proper content using url (YOUR_SCHEME://...)
                [self handleAirbridgeDeeplink:url];
            }];
            if (isAirbridgeDeeplink) { return; }
            // when app is opened with other deeplink
            // use existing logic as it is
        }
        ...
        @end
        ```
      </Tab>

      <Tab title="AppDelegate (Objective-C)">
        앱이 딥링크로 열릴 때 AppDelegate 클래스에서 호출되는 콜백은 아래와 같습니다.

        | 앱이 딥링크로 열리는 상황                          | 콜백                                                     |
        | --------------------------------------- | ------------------------------------------------------ |
        | 앱이 꺼지거나 백그라운드에 있는 상태에서 `URL 스킴` 으로 열릴 때 | `application:openURL:options:`                         |
        | 앱이 꺼지거나 백그라운드에 있는 상태에서 `유니버셜 링크` 로 열릴 때 | `application:continueUserActivity:restorationHandler:` |

        1. 앱이 에어브릿지 딥링크로 열렸을 때 유저를 이동시키는 함수를 구현하세요. 이는 유저를 의도한 화면으로 이동키시기 위해 각각의 콜백에 추가해야하는 함수입니다.

        ```objective-c lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        #import "AppDelegate.h"
        #import <Airbridge/Airbridge.h>

        @interface AppDelegate ()

        @end

        @implementation AppDelegate
        ...
        // when app is opened with airbridge deeplink
        - (void)handleAirbridgeDeeplink:(NSURL *)url {
            // show proper content using url (YOUR_SCHEME://...)
        }
        ...
        @end
        ```

        2. `application:openURL:options:` 콜백을 설정하세요. `trackDeeplink` 함수와 `handleDeeplink` 함수를 호출하여 딥링크 오픈 이벤트를 수집하고 위에서 구현한 함수를 호출하여 유저를 이동시키세요.

        ```objective-c lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        #import "AppDelegate.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 deeplink
            BOOL isAirbridgeDeeplink = [Airbridge handleDeeplinkWithUrl:url onSuccess:^(NSURL* url) {
                // when app is opened with airbridge deeplink
                // show proper content using url (YOUR_SCHEME://...)
                [self handleAirbridgeDeeplink:url];
            }];
            if (isAirbridgeDeeplink) { return; }
            // when app is opened with other deeplink
            // use existing logic as it is
            return isAirbridgeDeeplink;
        }
        ...
        @end
        ```

        3. `application:continueUserActivity:restorationHandler:` 콜백을 설정하세요. `trackDeeplink` 함수와 `handleDeeplink` 함수를 호출하여 딥링크 오픈 이벤트를 수집하고 위에서 구현한 함수를 호출하여 유저를 이동시키세요.

        ```objective-c lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        #import "AppDelegate.h"
        #import <Airbridge/Airbridge.h>

        @interface AppDelegate ()

        @end

        @implementation AppDelegate
        ...
        // when app is opened with universal links
        - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
            // track deeplink
            [Airbridge trackDeeplinkWithUserActivity:userActivity];
            // handle deeplink
            BOOL isAirbridgeDeeplink = [Airbridge handleDeeplinkWithUserActivity:userActivity onSuccess:^(NSURL* url) {
                // when app is opened with airbridge deeplink
                // show proper content using url (YOUR_SCHEME://...)
                [self handleAirbridgeDeeplink:url];
            }];
            if (isAirbridgeDeeplink) { return YES; }
            // when app is opened with other deeplink
            // use existing logic as it is
            return isAirbridgeDeeplink;
        }
        ...
        @end
        ```
      </Tab>
    </Tabs>
  </Accordion>
</AccordionGroup>

### 디퍼드 딥링크 설정하기

앱이 설치되지 않은 상태에서 디퍼드 딥링크를 설정한 트래킹 링크를 클릭하면 에어브릿지 딥링크를 저장합니다. 디퍼드 딥링크를 설정하면 에어브릿지 SDK는 아래와 같은 방식으로 딥링크를 획득합니다.

<Accordion title="에어브릿지 SDK의 디퍼드 딥링크 획득 방식">
  에어브릿지 SDK는 SDK 초기화 이후에 아래 조건을 모두 만족하면 딥링크 획득을 시도합니다. 획득 도중에 앱이 종료되면 에어브릿지 SDK는 저장된 에어브릿지 딥링크는 없는 것으로 처리됩니다.

  * 옵트인(Opt-In)을 설정한 상태에서  `Airbridge.startTracking` 함수를 호출합니다. 또는 옵트인을 설정하지 않았습니다.
  * ATT 추적 동의 여부가 결정되었습니다. 또는 ATT 프롬프트에서 설정한 이벤트 수집 지연 시간이 종료되었습니다.
</Accordion>

`Airbridge.handleDeferredDeeplink` 함수는 저장된 에어브릿지 딥링크를 획득한 후에 스킴 딥링크로 변환해 앱에 전달합니다. 변환된 스킴 딥링크를 활용해 유저를 설정한 목적지로 보냅니다.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
      .build()
  Airbridge.initializeSDK(option: option)
  ...
  let isFirstCalled = Airbridge.handleDeferredDeeplink() { url in
      // when handleDeferredDeeplink is called firstly after install
      if let url {
          // show proper content using url (YOUR_SCHEME://...)
      }
  }
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>
  ...
  AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                 token:@"YOUR_APP_SDK_TOKEN"];
  AirbridgeOption* option = [optionBuilder build];
  [Airbridge initializeSDKWithOption:option];
  ...
  BOOL isFirstCalled = [Airbridge handleDeferredDeeplinkOnSuccess:^(NSURL* url) {
      // when handleDeferredDeeplink is called firstly after install
      if (url != nil) {
          // show proper content using url (YOUR_SCHEME://...)
      }
  }];
  ```
</CodeGroup>

`Airbridge.handleDeferredDeeplink` 함수는 앱이 설치되고 처음으로 호출되었으면 true를 반환하고, 에어브릿지 딥링크 획득을 기다려 스킴 딥링크로 변환해 onSuccess로 전달합니다. 해당 스킴 딥링크를 활용해 유저를 설정한 목적지로 보낼 수 있습니다.

또는 저장된 에어브릿지 딥링크가 없으면 null을 onSuccess 전달합니다. SDK가 초기화되지 않았거나 `Airbridge.handleDeferredDeeplink` 함수를 처음으로 호출하지 않았다면 false를 전달합니다.

전달되는 스킴 딥링크는 일반적으로 `YOUR_SCHEME://...` 형태의 URL입니다. 메타 디퍼드 앱 링크(Meta Deferred App Links) 같은 서비스를 이용하면 다른 형태의 URL이 전달될 수 있습니다.

<Danger>
  **주의하세요.**

  앱이 딥링크로 열리면 에어브릿지는 디퍼드딥링크 유무에 관계없이 null을 onSuccess에 전달해서 딥링크만 처리되도록 합니다.
</Danger>

### 커스텀 도메인 설정하기

<Info>
  **알립니다**

  필수 설정 기능이 아닙니다. 필요한 경우에만 설정해 주세요.
</Info>

1. [유저가이드](/ko/guides/custom-domain)를 참고해서 대시보드에 커스텀 도메인을 설정하세요.
2. 에어브릿지 SDK 초기화시 `setTrackingLinkCustomDomains`함수를 사용하여 커스텀 도메인 링크를 추가하세요. `YOUR_APP_CUSTOM_DOMAIN` 은 정규화된 도메인 이름(FQDN: Fully Qualified Domain Name)을 입력하세요.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  // YOUR_APP_NAME: input your app name
  // YOUR_APP_SDK_TOKEN: input your app token
  // YOUR_APP_CUSTOM_DOMAIN: input your app custom domain. ex) example.domain.com
  let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME",
                                      token: "YOUR_APP_SDK_TOKEN")
      .setTrackingLinkCustomDomains(["YOUR_APP_CUSTOM_DOMAIN"])
      .build()
  Airbridge.initializeSDK(option: option)
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>
  ...
  // YOUR_APP_NAME: input your app name
  // YOUR_APP_SDK_TOKEN: input your app token
  // YOUR_APP_CUSTOM_DOMAIN: input your app custom domain. ex) example.domain.com
  AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                 token:@"YOUR_APP_SDK_TOKEN"];
  [optionBuilder setTrackingLinkCustomDomains:@[@"YOUR_APP_CUSTOM_DOMAIN"]];
  AirbridgeOption* option = [optionBuilder build];
  [Airbridge initializeSDKWithOption:option];
  ```
</CodeGroup>

<Danger>
  **주의하세요**

  추가한 커스텀 도메인은 Airbridge 대시보드에 설정된 정보와 일치해야 합니다.
</Danger>

## 인앱 이벤트

에어브릿지 SDK가 서비스에서 발생한 유저의 특정 행동을 설정에 따라 수집한 후에 인앱 이벤트로 전송합니다.

* [에어브릿지 이벤트 살펴보기 (유저 가이드)](/ko/guides/airbridge-event)

### 인앱 이벤트 전송하기

<Note>
  **하이브리드 앱 설정하기**

  하이브리드 앱에서 웹 사이트 코드를 변경하지 않아도 인앱 웹 사이트에서 발생하는 에어브릿지 관련 작업을 iOS SDK가 처리하도록 설정할 수 있습니다.

  * [하이브리드 앱 설정하기 (v4)](/ko/developers/hybrid-app-settings-ios-sdk-v4)
</Note>

이벤트를 전송하기 위해서는 `Airbridge.trackEvent` 함수를 호출해야 합니다. `Airbridge.trackEvent` 함수 구성요소의 필수 여부와 타입은 아래와 같습니다.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  static func trackEvent(
      category: String
  )

  static func trackEvent(
      category: String,
      semanticAttributes: [String : Any]
  )

  static func trackEvent(
      category: String,
      semanticAttributes: [String : Any],
      customAttributes: [String : Any]
  )
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  + (void)trackEventWithCategory:(NSString*)category
  + (void)trackEventWithCategory:(NSString*)category
              semanticAttributes:(NSDictionary*)semanticAttributes
  + (void)trackEventWithCategory:(NSString*)category
              semanticAttributes:(NSDictionary*)semanticAttributes
                customAttributes:(NSDictionary*)customAttributes
  ```
</CodeGroup>

| 구성요소               | 필수 여부 | 타입             | 설명             |
| ------------------ | ----- | -------------- | -------------- |
| category           | 필수    | String         | 이벤트의 카테고리      |
| semanticAttributes | 선택    | \[String: Any] | 이벤트의 시맨틱 어트리뷰트 |
| customAttributes   | 선택    | \[String: Any] | 이벤트의 커스텀 어트리뷰트 |

각 구성요소의 정의와 사용할 수 있는 문자열을 아래에서 확인해 주세요.

<AccordionGroup>
  <Accordion title="카테고리">
    AirbridgeCategory에서 에어브릿지 SDK가 제공하는 스탠다드 이벤트 카테고리를 확인할 수 있습니다. 또는 스탠다드 이벤트 목록에서 확인한 이벤트 카테고리를 입력합니다.

    * [스탠다드 이벤트 목록](/ko/guides/airbridge-event-types#스탠다드-이벤트-목록)

    커스텀 이벤트는 [이벤트 택소노미](/ko/guides/airbridge-event-taxonomy)에서 정한 이벤트 이름을 입력하면 전송할 수 있습니다.

    아래 예시를 참고해 주세요.

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      // track standard event (provided by sdk)
      Airbridge.trackEvent(category: AirbridgeCategory.ORDER_COMPLETED)
      // track standard event (not provided by sdk)
      Airbridge.trackEvent(category: "airbridge.ecommerce.order.canceled")
      // track custom event
      Airbridge.trackEvent(category: "eventViewed")
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      // track standard event (provided by sdk)
      [Airbridge trackEventWithCategory:AirbridgeCategory.ORDER_COMPLETED];
      // track standard event (not provided by sdk)
      [Airbridge trackEventWithCategory:@"airbridge.ecommerce.order.canceled"];
      // track custom event
      [Airbridge trackEventWithCategory:@"eventViewed"];
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="어트리뷰트">
    <Danger>
      **주의하세요**

      에어브릿지 SDK v4의 어트리뷰트는 이전 버전과 다릅니다. 이전 버전의 어트리뷰트에는 액션, 라벨, 밸류가 포함되지 않습니다.
    </Danger>

    어트리뷰트로 이벤트의 추가 정보를 수집할 수 있습니다.

    * 액션, 라벨: 에어브릿지 리포트에서 그룹바이로 활용할 수 있는 정보를 수집합니다.
    * 밸류: 매출 분석에 활용하는 정보를 수집합니다. 밸류로 수집한 데이터는 자유롭게 사칙연산에 활용할 수 있습니다.
    * 시맨틱 어트리뷰트: 에어브릿지가 미리 정의한 어트리뷰트입니다.
    * 커스텀 어트리뷰트: 에어브릿지 사용자가 정의한 어트리뷰트입니다.

    `Airbridge.trackEvent` 함수의 semanticAttributes 파라미터를 통해 액션, 라벨, 밸류, 시맨틱 어트리뷰트를 입력하고 customAttributes 파라미터를 통해 커스텀 어트리뷰트를 입력할 수 있습니다.

    에어브릿지가 제공하는 시맨틱 어트리뷰트 목록은 아래에서 확인할 수 있습니다.

    * [시맨틱 어트리뷰트 목록](/ko/guides/airbridge-event-elements#시맨틱-어트리뷰트-목록)

    아래 예시를 참고해 주세요.

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.ORDER_COMPLETED,
          semanticAttributes: [
              // action
              AirbridgeAttribute.ACTION: "Tool",
              // label
              AirbridgeAttribute.LABEL: "Hammer",
              // value
              AirbridgeAttribute.VALUE: 10,
              // semantic attribute (provided by sdk)
              AirbridgeAttribute.CURRENCY: "USD",
              AirbridgeAttribute.PRODUCTS: [
                  [
                      // semantic attribute value (provided by sdk)
                      AirbridgeAttribute.PRODUCT_ID: "12345",
                      // semantic attribute value (not provided by sdk)
                      "name": "PlasticHammer",
                  ],
              ],
              // semantic attribute (not provided by sdk)
              "totalQuantity": 1,
          ],
          customAttributes: [
              // custom attribute
              "promotion": "FirstPurchasePromotion",
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #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",
      }];
      ```
    </CodeGroup>

    <Danger>
      **주의하세요**

      시멘틱 어트리뷰트와 커스텀 어트리뷰트는 JSON만 데이터 타입으로 허용합니다.

      * JSON 타입: String, Number, Boolean, Object\<String, JSON>, Array\<JSON>
      * 시멘틱 어트리뷰트와 커스텀 어트리뷰트에 사용할 수 없는 타입: Struct, Class 등
    </Danger>
  </Accordion>
</AccordionGroup>

SDK가 제공하는 스탠다드 이벤트 카테고리와 시맨틱 어트리뷰트는 아래와 같습니다.

<AccordionGroup>
  <Accordion title="SDK가 제공하는 스탠다드 이벤트 카테고리(AirbridgeCategory)">
    | 키                       | 데이터                                      |
    | ----------------------- | ---------------------------------------- |
    | SIGN\_UP                | airbridge.user.signup                    |
    | SIGN\_IN                | airbridge.user.signin                    |
    | SIGN\_OUT               | airbridge.user.signout                   |
    | HOME\_VIEWED            | airbridge.ecommerce.home.viewed          |
    | PRODUCT\_LIST\_VIEWED   | airbridge.ecommerce.productList.viewed   |
    | SEARCH\_RESULTS\_VIEWED | airbridge.ecommerce.searchResults.viewed |
    | PRODUCT\_VIEWED         | airbridge.ecommerce.product.viewed       |
    | ADD\_PAYMENT\_INFO      | airbridge.addPaymentInfo                 |
    | ADD\_TO\_WISHLIST       | airbridge.addToWishlist                  |
    | ADDED\_TO\_CART         | airbridge.ecommerce.product.addedToCart  |
    | INITIATE\_CHECKOUT      | airbridge.initiateCheckout               |
    | ORDER\_COMPLETED        | airbridge.ecommerce.order.completed      |
    | ORDER\_CANCELED         | airbridge.ecommerce.order.canceled       |
    | START\_TRIAL            | airbridge.startTrial                     |
    | SUBSCRIBE               | airbridge.subscribe                      |
    | UNSUBSCRIBE             | airbridge.unsubscribe                    |
    | AD\_IMPRESSION          | airbridge.adImpression                   |
    | AD\_CLICK               | airbridge.adClick                        |
    | COMPLETE\_TUTORIAL      | airbridge.completeTutorial               |
    | ACHIEVE\_LEVEL          | airbridge.achieveLevel                   |
    | UNLOCK\_ACHIEVEMENT     | airbridge.unlockAchievement              |
    | RATE                    | airbridge.rate                           |
    | SHARE                   | airbridge.share                          |
    | SCHEDULE                | airbridge.schedule                       |
    | SPEND\_CREDITS          | airbridge.spendCredits                   |
  </Accordion>

  <Accordion title="SDK가 제공하는 시맨틱 어트리뷰트(AirbridgeAttribute)">
    | 키                                     | 데이터                             | 데이터 형식  |
    | ------------------------------------- | ------------------------------- | ------- |
    | ACTION                                | action                          | string  |
    | LABEL                                 | label                           | string  |
    | VALUE                                 | value                           | float   |
    | CURRENCY                              | currency                        | string  |
    | PRODUCTS                              | products                        | array   |
    | PRODUCT\_ID                           | productID                       | string  |
    | PRODUCT\_NAME                         | name                            | string  |
    | PRODUCT\_PRICE                        | price                           | float   |
    | PRODUCT\_QUANTITY                     | quantity                        | int     |
    | PRODUCT\_CURRENCY                     | currency                        | string  |
    | PRODUCT\_POSITION                     | position                        | int     |
    | PRODUCT\_CATEGORY\_ID                 | categoryID                      | string  |
    | PRODUCT\_CATEGORY\_NAME               | categoryName                    | string  |
    | PRODUCT\_BRAND\_ID                    | brandID                         | string  |
    | PRODUCT\_BRAND\_NAME                  | brandName                       | string  |
    | PERIOD                                | period                          | string  |
    | IS\_RENEWAL                           | isRenewal                       | boolean |
    | RENEWAL\_COUNT                        | renewalCount                    | int     |
    | PRODUCT\_LIST\_ID                     | productListID                   | string  |
    | CART\_ID                              | cartID                          | string  |
    | TRANSACTION\_ID                       | transactionID                   | string  |
    | TRANSACTION\_TYPE                     | transactionType                 | string  |
    | TRANSACTION\_PAIRED\_EVENT\_CATEGORY  | transactionPairedEventCategory  | string  |
    | TRANSACTION\_PAIRED\_EVENT\_TIMESTAMP | transactionPairedEventTimestamp | int     |
    | TOTAL\_QUANTITY                       | totalQuantity                   | int     |
    | QUERY                                 | query                           | string  |
    | IN\_APP\_PURCHASED                    | inAppPurchased                  | boolean |
    | CONTRIBUTION\_MARGIN                  | contributionMargin              | float   |
    | LIST\_ID                              | listID                          | string  |
    | RATE\_ID                              | rateID                          | string  |
    | RATE                                  | rate                            | float   |
    | MAX\_RATE                             | maxRate                         | float   |
    | ACHIEVEMENT\_ID                       | achievementID                   | string  |
    | SHARED\_CHANNEL                       | sharedChannel                   | string  |
    | DATE\_TIME                            | datetime                        | string  |
    | DESCRIPTION                           | description                     | string  |
    | IS\_REVENUE                           | isRevenue                       | boolean |
    | PLACE                                 | place                           | string  |
    | SCHEDULE\_ID                          | scheduleID                      | string  |
    | TYPE                                  | type                            | string  |
    | LEVEL                                 | level                           | string  |
    | SCORE                                 | score                           | float   |
    | AD\_PARTNERS                          | adPartners                      | array   |
    | IS\_FIRST\_PER\_USER                  | isFirstPerUser                  | boolean |
  </Accordion>
</AccordionGroup>

아래 데이터 유형별 예시 코드를 참고해 주세요.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  Airbridge.trackEvent(
      category: "event",
      semanticAttributes: [
          AirbridgeAttribute.VALUE: 10,
      ],
      customAttributes: [
          "string": "string",
          "number": 1000,
          "boolean": true,
          "object": ["key": "value"],
          "array": ["value"],
      ]
  )
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>
  ...
  [Airbridge trackEventWithCategory:@"event" semanticAttributes:@{
      AirbridgeAttribute.VALUE: @(10),
  } customAttributes:@{
      @"string": "string",
      @"number": @(1000),
      @"boolean": @(YES),
      @"object": @{@"key": @"value"},
      @"array": @[@"value"],
      @"key": @"value",
  }];
  ```
</CodeGroup>

### 인앱 이벤트 추가 설정하기

<Info>
  **알립니다**

  설정하지 않아도 기본 설정이 적용되어 있습니다. 추가 설정 필요한지 검토한 후에 진행해 주세요.
</Info>

전송하는 인앱 이벤트에 필요한 설정을 추가할 수 있습니다.

<AccordionGroup>
  <Accordion title="인앱 이벤트 세션 설정하기">
    에어브릿지 SDK는 이벤트 데이터에 세션 정보를 포함하여 전송합니다.

    앱이 백그라운드로 전환되거나 프로세스가 종료되면 백그라운드 진입 시간이 기록되고, 앱이 포그라운드로 전환되거나 프로세스가 실행되면 재진입 시간이 기록됩니다. 마지막 백그라운드 진입 시간과 재진입 시간의 차이가 세션 만료 시간보다 길 경우, 이전 세션은 종료되고 새로운 세션이 시작됩니다.

    기본 세션 타임아웃은 300초(5분)입니다. `setSessionTimeout` 함수를 사용하면 이 값을 최대 604,800초(7일)까지 변경할 수 있습니다.

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
          .setSessionTimeout(second: 300)
          .build()
      Airbridge.initializeSDK(option: option)
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                     token:@"YOUR_APP_SDK_TOKEN"];
      [optionBuilder setSessionTimeoutWithSecond:300];
      AirbridgeOption* option = [optionBuilder build];
      [Airbridge initializeSDKWithOption:option];
      ```
    </CodeGroup>

    <Danger>
      **주의하세요**

      에어브릿지 SDK는 새로운 세션을 시작하는 실행(Open), 포어그라운드(Foregroud) 이벤트는 수집합니다. 세션이 유지되는 중에는 해당 이벤트를 수집하지 않습니다. 해당 이벤트를 세션 유지 중에 수집하기 위해서는 [추가 설정](#세션내-생명주기-이벤트-수집하기)이 필요합니다.
    </Danger>
  </Accordion>

  <Accordion title="인앱 이벤트 전송 주기 설정하기">
    기본 이벤트 전송 주기는 0초입니다. `setEventTransmitInterval` 함수를 이용하면 최대 86,400초(1일)까지 설정할 수 있습니다.

    아래 예시를 참고해 주세요.

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
          .setEventTransmitInterval(second: 0)
          .build()
      Airbridge.initializeSDK(option: option)
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                     token:@"YOUR_APP_SDK_TOKEN"];
      [optionBuilder setEventTransmitIntervalWithSecond:0];
      AirbridgeOption* option = [optionBuilder build];
      [Airbridge initializeSDKWithOption:option];
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="인앱 이벤트 저장 용량 설정하기">
    SDK가 저장할 수 있는 이벤트 개수와 이벤트 저장 용량의 기본 및 최대 설정값은 다음과 같습니다.

    |     | 이벤트 개수   | 저장 용량           |
    | --- | -------- | --------------- |
    | 기본값 | INT\_MAX | 1024 GiB(기비바이트) |
    | 최대값 | INT\_MAX | 1024 GiB(기비바이트) |

    이벤트 개수를 제한하려면 `setEventBufferCountLimit` 함수를, 이벤트 저장 용량을 제한하려면 `setEventBufferSizeLimit` 함수를 사용하여 개별 설정할 수 있습니다.

    아래 예시를 참고해 주세요.

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_TOKEN")
          .setEventBufferCountLimit(Int.max)
          .setEventBufferSizeLimit(gibibyte: 1024)
          .build()
      Airbridge.initializeSDK(option: option)
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                     token:@"YOUR_APP_TOKEN"];
      [optionBuilder setEventBufferCountLimit:INT_MAX];
      [optionBuilder setEventBufferSizeLimitWithGibibyte:1024];
      AirbridgeOption* option = [optionBuilder build];
      [Airbridge initializeSDKWithOption:option];
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="전송되지 않은 이벤트 삭제하기">
    이벤트 삭제 옵션을 활성화하면 에어브릿지 SDK 초기화 과정에서 전송되지 않고 저장된 인앱 이벤트를 모두 삭제합니다. 기본 이벤트 삭제 옵션은 비활성화입니다.

    `setClearEventBufferOnInitializeEnabled` 함수를 true로 설정하면 이벤트 삭제 옵션이 활성화됩니다.

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_TOKEN")
          .setClearEventBufferOnInitializeEnabled(true)
          .build()
      Airbridge.initializeSDK(option: option)
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                     token:@"YOUR_APP_TOKEN"];
      [optionBuilder setClearEventBufferOnInitializeEnabled:YES];
      AirbridgeOption* option = [optionBuilder build];
      [Airbridge initializeSDKWithOption:option];
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="디바이스 식별자 설정하기">
    에어브릿지 SDK는 디바이스 식별자를 모든 이벤트에 포함해 전송하는 기능을 지원합니다.

    | <span style={{ display: 'inline-block', minWidth: '140px' }}>함수</span> | <span style={{ display: 'inline-block', minWidth: '240px' }}>설명</span>                                                              |
    | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
    | `Airbridge.setDeviceAlias`                                             | 디바이스 식별자를 추가로 입력합니다. 최대 10개 입력할 수 있습니다.<br />- key: 최대 128자입니다. `^[a-zA-Z_][a-zA-Z0-9_]*$` 정규식을 만족해야 합니다.<br />- value: 최대 128자입니다. |
    | `Airbridge.removeDeviceAlias`                                          | 디바이스 식별자 중에서 지정한 디바이스 식별자를 삭제합니다.                                                                                                   |
    | `Airbridge.clearDeviceAlias`                                           | 디바이스 식별자를 모두 삭제합니다.                                                                                                                 |

    아래 예시를 참고해 주세요.

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.setDeviceAlias(key: "string", value: "string")
      Airbridge.removeDeviceAlias(key: "string")
      Airbridge.clearDeviceAlias()
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge setDeviceAliasWithKey:@"string" value:@"string"];
      [Airbridge removeDeviceAliasWithKey:@"string"];
      [Airbridge clearDeviceAlias];
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

### 인앱 이벤트 예시 코드

에어브릿지가 수집하는 주요 인앱 이벤트는 스탠다드 이벤트와 커스텀 이벤트입니다. 스탠다드 이벤트는 에어브릿지가 정의한 이벤트입니다. 아래 예시 코드를 참고해 주세요.

<AccordionGroup>
  <Accordion title="회원가입, 로그인, 로그아웃, 홈화면 조회, 상품리스트 조회">
    ###### 회원가입

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.setUserID("string")
      Airbridge.setUserAlias(key: "string", value: "string")
      Airbridge.setUserEmail("string")
      Airbridge.setUserPhone("string")
      Airbridge.setUserAttribute(key: "string", value: "string")

      Airbridge.trackEvent(
          category: AirbridgeCategory.SIGN_UP
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge setUserID:@"string"];
      [Airbridge setUserAliasWithKey:@"string" value:@"string"];
      [Airbridge setUserEmail:@"string"];
      [Airbridge setUserPhone:@"string"];
      [Airbridge setUserAttributeWithKey:@"string" value:@"string"];

      [Airbridge trackEventWithCategory:AirbridgeCategory.SIGN_UP];
      ```
    </CodeGroup>

    ###### 로그인

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.setUserID("string")
      Airbridge.setUserAlias(key: "string", value: "string")
      Airbridge.setUserEmail("string")
      Airbridge.setUserPhone("string")
      Airbridge.setUserAttribute(key: "string", value: "string")

      Airbridge.trackEvent(
          category: AirbridgeCategory.SIGN_IN
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge setUserID:@"string"];
      [Airbridge setUserAliasWithKey:@"string" value:@"string"];
      [Airbridge setUserEmail:@"string"];
      [Airbridge setUserPhone:@"string"];
      [Airbridge setUserAttributeWithKey:@"string" value:@"string"];

      [Airbridge trackEventWithCategory:AirbridgeCategory.SIGN_IN];
      ```
    </CodeGroup>

    ###### 로그아웃

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.SIGN_OUT
      )

      Airbridge.clearUser()
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.SIGN_OUT];

      [Airbridge clearUser];
      ```
    </CodeGroup>

    ###### 홈화면 조회

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.HOME_VIEWED
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.HOME_VIEWED];
      ```
    </CodeGroup>

    ###### 상품리스트 조회

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.PRODUCT_LIST_VIEWED, 
          semanticAttributes: [
              AirbridgeAttribute.LIST_ID: "84e6e236-38c4-48db-9b49-16e4cc064386",
              AirbridgeAttribute.PRODUCT_CURRENCY: "USD",
              AirbridgeAttribute.PRODUCTS: [
                  [
                      AirbridgeAttribute.PRODUCT_ID: "0117b32a-5a6c-4d4c-b64c-7858e07dba78",
                      AirbridgeAttribute.PRODUCT_NAME: "PlasticHammer",
                      AirbridgeAttribute.PRODUCT_PRICE: 10,
                      AirbridgeAttribute.PRODUCT_QUANTITY: 1,
                      AirbridgeAttribute.PRODUCT_CURRENCY: "USD"
                  ],
                  [
                      AirbridgeAttribute.PRODUCT_ID: "d6ab2fbe-decc-4362-b719-d257a131e91e",
                      AirbridgeAttribute.PRODUCT_NAME: "PlasticFork",
                      AirbridgeAttribute.PRODUCT_PRICE: 1,
                      AirbridgeAttribute.PRODUCT_QUANTITY: 1,
                      AirbridgeAttribute.PRODUCT_CURRENCY: "USD"
                  ],
              ],
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.PRODUCT_LIST_VIEWED semanticAttributes:@{
          AirbridgeAttribute.LIST_ID: @"84e6e236-38c4-48db-9b49-16e4cc064386",
          AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
          AirbridgeAttribute.PRODUCTS: @[
              @{
                  AirbridgeAttribute.PRODUCT_ID: @"0117b32a-5a6c-4d4c-b64c-7858e07dba78",
                  AirbridgeAttribute.PRODUCT_NAME: @"PlasticHammer",
                  AirbridgeAttribute.PRODUCT_PRICE: @(10),
                  AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
                  AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
              },
              @{
                  AirbridgeAttribute.PRODUCT_ID: @"d6ab2fbe-decc-4362-b719-d257a131e91e",
                  AirbridgeAttribute.PRODUCT_NAME: @"PlasticFork",
                  AirbridgeAttribute.PRODUCT_PRICE: @(1),
                  AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
                  AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
              },
          ],
      }];
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="검색결과 조회, 상품상세페이지 조회, 결제수단 등록, 위시리스트 추가, 장바구니 담기">
    ###### 검색결과 조회

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.SEARCH_RESULTS_VIEWED, 
          semanticAttributes: [
              AirbridgeAttribute.QUERY: "Plastic",
              AirbridgeAttribute.PRODUCT_CURRENCY: "USD",
              AirbridgeAttribute.PRODUCTS: [
                  [
                      AirbridgeAttribute.PRODUCT_ID: "0117b32a-5a6c-4d4c-b64c-7858e07dba78",
                      AirbridgeAttribute.PRODUCT_NAME: "PlasticHammer",
                      AirbridgeAttribute.PRODUCT_PRICE: 10,
                      AirbridgeAttribute.PRODUCT_QUANTITY: 1,
                      AirbridgeAttribute.PRODUCT_CURRENCY: "USD"
                  ],
                  [
                      AirbridgeAttribute.PRODUCT_ID: "d6ab2fbe-decc-4362-b719-d257a131e91e",
                      AirbridgeAttribute.PRODUCT_NAME: "PlasticFork",
                      AirbridgeAttribute.PRODUCT_PRICE: 1,
                      AirbridgeAttribute.PRODUCT_QUANTITY: 1,
                      AirbridgeAttribute.PRODUCT_CURRENCY: "USD"
                  ],
              ],
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.SEARCH_RESULTS_VIEWED semanticAttributes:@{
          AirbridgeAttribute.QUERY: @"Plastic",
          AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
          AirbridgeAttribute.PRODUCTS: @[
              @{
                  AirbridgeAttribute.PRODUCT_ID: @"0117b32a-5a6c-4d4c-b64c-7858e07dba78",
                  AirbridgeAttribute.PRODUCT_NAME: @"PlasticHammer",
                  AirbridgeAttribute.PRODUCT_PRICE: @(10),
                  AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
                  AirbridgeAttribute.PRODUCT_CURRENCY: @"USD"
              },
              @{
                  AirbridgeAttribute.PRODUCT_ID: @"d6ab2fbe-decc-4362-b719-d257a131e91e",
                  AirbridgeAttribute.PRODUCT_NAME: @"PlasticFork",
                  AirbridgeAttribute.PRODUCT_PRICE: @(1),
                  AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
                  AirbridgeAttribute.PRODUCT_CURRENCY: @"USD"
              },
          ],
      }];
      ```
    </CodeGroup>

    ###### 상품상세페이지 조회

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.PRODUCT_VIEWED, 
          semanticAttributes: [
              AirbridgeAttribute.PRODUCTS: [
                  [
                      AirbridgeAttribute.PRODUCT_ID: "0117b32a-5a6c-4d4c-b64c-7858e07dba78",
                      AirbridgeAttribute.PRODUCT_NAME: "PlasticHammer",
                      AirbridgeAttribute.PRODUCT_PRICE: 10,
                      AirbridgeAttribute.PRODUCT_QUANTITY: 1,
                      AirbridgeAttribute.PRODUCT_CURRENCY: "USD",
                  ],
              ],
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.PRODUCT_VIEWED semanticAttributes:@{
          AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
          AirbridgeAttribute.PRODUCTS: @[
              @{
                  AirbridgeAttribute.PRODUCT_ID: @"0117b32a-5a6c-4d4c-b64c-7858e07dba78",
                  AirbridgeAttribute.PRODUCT_NAME: @"PlasticHammer",
                  AirbridgeAttribute.PRODUCT_PRICE: @(10),
                  AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
                  AirbridgeAttribute.PRODUCT_CURRENCY: @"USD"
              },
          ],
      }];
      ```
    </CodeGroup>

    ###### 결제수단 등록

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.ADD_PAYMENT_INFO, 
          semanticAttributes: [
              AirbridgeAttribute.TYPE: "CreditCard",
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.ADD_PAYMENT_INFO semanticAttributes:@{
          AirbridgeAttribute.TYPE: @"CreditCard",
      }];
      ```
    </CodeGroup>

    ###### 위시리스트 추가

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.ADD_TO_WISHLIST, 
          semanticAttributes: [
              AirbridgeAttribute.LIST_ID: "189a2f8b-83ee-4074-8158-726be54e57d4",
              AirbridgeAttribute.CURRENCY: "USD",
              AirbridgeAttribute.PRODUCTS: [
                  [
                      AirbridgeAttribute.PRODUCT_ID: "0117b32a-5a6c-4d4c-b64c-7858e07dba78",
                      AirbridgeAttribute.PRODUCT_NAME: "PlasticHammer",
                      AirbridgeAttribute.PRODUCT_PRICE: 10,
                      AirbridgeAttribute.PRODUCT_QUANTITY: 1,
                      AirbridgeAttribute.PRODUCT_CURRENCY: "USD"
                  ],
              ],
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.ADD_TO_WISHLIST semanticAttributes:@{
          AirbridgeAttribute.LIST_ID: @"189a2f8b-83ee-4074-8158-726be54e57d4",
          AirbridgeAttribute.CURRENCY: @"USD",
          AirbridgeAttribute.PRODUCTS: @[
              @{
                  AirbridgeAttribute.PRODUCT_ID: @"0117b32a-5a6c-4d4c-b64c-7858e07dba78",
                  AirbridgeAttribute.PRODUCT_NAME: @"PlasticHammer",
                  AirbridgeAttribute.PRODUCT_PRICE: @(10),
                  AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
                  AirbridgeAttribute.PRODUCT_CURRENCY: @"USD"
              },
          ],
      }];
      ```
    </CodeGroup>

    ###### 장바구니 담기

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.ADDED_TO_CART, 
          semanticAttributes: [
              AirbridgeAttribute.CART_ID: "421eaeb7-6e80-4694-933e-f2e1a55e9cbd",
              AirbridgeAttribute.CURRENCY: "USD",
              AirbridgeAttribute.PRODUCTS: [
                  [
                      AirbridgeAttribute.PRODUCT_ID: "0117b32a-5a6c-4d4c-b64c-7858e07dba78",
                      AirbridgeAttribute.PRODUCT_NAME: "PlasticHammer",
                      AirbridgeAttribute.PRODUCT_PRICE: 10,
                      AirbridgeAttribute.PRODUCT_QUANTITY: 1,
                      AirbridgeAttribute.PRODUCT_CURRENCY: "USD"
                  ],
              ],
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.ADDED_TO_CART semanticAttributes:@{
          AirbridgeAttribute.CART_ID: @"421eaeb7-6e80-4694-933e-f2e1a55e9cbd",
          AirbridgeAttribute.CURRENCY: @"USD",
          AirbridgeAttribute.PRODUCTS: @[
              @{
                  AirbridgeAttribute.PRODUCT_ID: @"0117b32a-5a6c-4d4c-b64c-7858e07dba78",
                  AirbridgeAttribute.PRODUCT_NAME: @"PlasticHammer",
                  AirbridgeAttribute.PRODUCT_PRICE: @(10),
                  AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
                  AirbridgeAttribute.PRODUCT_CURRENCY: @"USD"
              },
          ],
      }];
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="결제 시작, 구매 완료, 구매 취소, 체험판 시작, 구독, 구독 취소">
    ###### 결제 시작

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.INITIATE_CHECKOUT, 
          semanticAttributes: [
              AirbridgeAttribute.TRANSACTION_ID: "0a7ee1ec-33da-4ffb-b775-89e80e75978a",
              AirbridgeAttribute.CURRENCY: "USD",
              AirbridgeAttribute.PRODUCTS: [
                  [
                      AirbridgeAttribute.PRODUCT_ID: "0117b32a-5a6c-4d4c-b64c-7858e07dba78",
                      AirbridgeAttribute.PRODUCT_NAME: "PlasticHammer",
                      AirbridgeAttribute.PRODUCT_PRICE: 10,
                      AirbridgeAttribute.PRODUCT_QUANTITY: 1,
                      AirbridgeAttribute.PRODUCT_CURRENCY: "USD"
                  ],
                  [
                      AirbridgeAttribute.PRODUCT_ID: "d6ab2fbe-decc-4362-b719-d257a131e91e",
                      AirbridgeAttribute.PRODUCT_NAME: "PlasticFork",
                      AirbridgeAttribute.PRODUCT_PRICE: 1,
                      AirbridgeAttribute.PRODUCT_QUANTITY: 1,
                      AirbridgeAttribute.PRODUCT_CURRENCY: "USD"
                  ],
              ],
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.INITIATE_CHECKOUT semanticAttributes:@{
          AirbridgeAttribute.TRANSACTION_ID: @"0a7ee1ec-33da-4ffb-b775-89e80e75978a",
          AirbridgeAttribute.CURRENCY: @"USD",
          AirbridgeAttribute.PRODUCTS: @[
              @{
                  AirbridgeAttribute.PRODUCT_ID: @"0117b32a-5a6c-4d4c-b64c-7858e07dba78",
                  AirbridgeAttribute.PRODUCT_NAME: @"PlasticHammer",
                  AirbridgeAttribute.PRODUCT_PRICE: @(10),
                  AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
                  AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
              },
              @{
                  AirbridgeAttribute.PRODUCT_ID: @"d6ab2fbe-decc-4362-b719-d257a131e91e",
                  AirbridgeAttribute.PRODUCT_NAME: @"PlasticFork",
                  AirbridgeAttribute.PRODUCT_PRICE: @(1),
                  AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
                  AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
              },
          ],
      }];
      ```
    </CodeGroup>

    ###### 구매 완료

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.ORDER_COMPLETED, 
          semanticAttributes: [
              AirbridgeAttribute.VALUE: 11,
              AirbridgeAttribute.TRANSACTION_ID: "8065ef16-162b-4a82-b683-e51aefdda7d5",
              AirbridgeAttribute.CURRENCY: "USD",
              AirbridgeAttribute.IN_APP_PURCHASED: true,
              AirbridgeAttribute.PRODUCTS: [
                  [
                      AirbridgeAttribute.PRODUCT_ID: "0117b32a-5a6c-4d4c-b64c-7858e07dba78",
                      AirbridgeAttribute.PRODUCT_NAME: "PlasticHammer",
                      AirbridgeAttribute.PRODUCT_PRICE: 10,
                      AirbridgeAttribute.PRODUCT_QUANTITY: 1,
                      AirbridgeAttribute.PRODUCT_CURRENCY: "USD"
                  ],
                  [
                      AirbridgeAttribute.PRODUCT_ID: "d6ab2fbe-decc-4362-b719-d257a131e91e",
                      AirbridgeAttribute.PRODUCT_NAME: "PlasticFork",
                      AirbridgeAttribute.PRODUCT_PRICE: 1,
                      AirbridgeAttribute.PRODUCT_QUANTITY: 1,
                      AirbridgeAttribute.PRODUCT_CURRENCY: "USD"
                  ],
              ],
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.ORDER_COMPLETED semanticAttributes:@{
          AirbridgeAttribute.VALUE: @(11),
          AirbridgeAttribute.TRANSACTION_ID: @"8065ef16-162b-4a82-b683-e51aefdda7d5",
          AirbridgeAttribute.CURRENCY: @"USD",
          AirbridgeAttribute.IN_APP_PURCHASED: @(YES),
          AirbridgeAttribute.PRODUCTS: @[
              @{
                  AirbridgeAttribute.PRODUCT_ID: @"0117b32a-5a6c-4d4c-b64c-7858e07dba78",
                  AirbridgeAttribute.PRODUCT_NAME: @"PlasticHammer",
                  AirbridgeAttribute.PRODUCT_PRICE: @(10),
                  AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
                  AirbridgeAttribute.PRODUCT_CURRENCY: @"USD"
              },
              @{
                  AirbridgeAttribute.PRODUCT_ID: @"d6ab2fbe-decc-4362-b719-d257a131e91e",
                  AirbridgeAttribute.PRODUCT_NAME: @"PlasticFork",
                  AirbridgeAttribute.PRODUCT_PRICE: @(1),
                  AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
                  AirbridgeAttribute.PRODUCT_CURRENCY: @"USD"
              },
          ],
      }];
      ```
    </CodeGroup>

    ###### 구매 취소

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.ORDER_CANCELED, 
          semanticAttributes: [
              AirbridgeAttribute.VALUE: 11,
              AirbridgeAttribute.TRANSACTION_ID: "8065ef16-162b-4a82-b683-e51aefdda7d5",
              AirbridgeAttribute.CURRENCY: "USD",
              AirbridgeAttribute.IN_APP_PURCHASED: true,
              AirbridgeAttribute.PRODUCTS: [
                  [
                      AirbridgeAttribute.PRODUCT_ID: "0117b32a-5a6c-4d4c-b64c-7858e07dba78",
                      AirbridgeAttribute.PRODUCT_NAME: "PlasticHammer",
                      AirbridgeAttribute.PRODUCT_PRICE: 10,
                      AirbridgeAttribute.PRODUCT_QUANTITY: 1,
                      AirbridgeAttribute.PRODUCT_CURRENCY: "USD"
                  ],
                  [
                      AirbridgeAttribute.PRODUCT_ID: "d6ab2fbe-decc-4362-b719-d257a131e91e",
                      AirbridgeAttribute.PRODUCT_NAME: "PlasticFork",
                      AirbridgeAttribute.PRODUCT_PRICE: 1,
                      AirbridgeAttribute.PRODUCT_QUANTITY: 1,
                      AirbridgeAttribute.PRODUCT_CURRENCY: "USD"
                  ],
              ],
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.ORDER_CANCELED semanticAttributes:@{
          AirbridgeAttribute.VALUE: @(11),
          AirbridgeAttribute.TRANSACTION_ID: @"8065ef16-162b-4a82-b683-e51aefdda7d5",
          AirbridgeAttribute.CURRENCY: @"USD",
          AirbridgeAttribute.IN_APP_PURCHASED: @(YES),
          AirbridgeAttribute.PRODUCTS: @[
              @{
                  AirbridgeAttribute.PRODUCT_ID: @"0117b32a-5a6c-4d4c-b64c-7858e07dba78",
                  AirbridgeAttribute.PRODUCT_NAME: @"PlasticHammer",
                  AirbridgeAttribute.PRODUCT_PRICE: @(10),
                  AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
                  AirbridgeAttribute.PRODUCT_CURRENCY: @"USD"
              },
              @{
                  AirbridgeAttribute.PRODUCT_ID: @"d6ab2fbe-decc-4362-b719-d257a131e91e",
                  AirbridgeAttribute.PRODUCT_NAME: @"PlasticFork",
                  AirbridgeAttribute.PRODUCT_PRICE: @(1),
                  AirbridgeAttribute.PRODUCT_QUANTITY: @(1),
                  AirbridgeAttribute.PRODUCT_CURRENCY: @"USD"
              },
          ],
      }];
      ```
    </CodeGroup>

    ###### 체험판 시작

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.START_TRIAL, 
          semanticAttributes: [
              AirbridgeAttribute.TRANSACTION_ID: "ef1e5271-0370-407c-b1e9-669a8df1dc2c",
              AirbridgeAttribute.CURRENCY: "USD",
              AirbridgeAttribute.PERIOD: "P1M",
              AirbridgeAttribute.PRODUCTS: [
                  [
                      AirbridgeAttribute.PRODUCT_ID: "306a57cb-f653-4220-a208-8405d8e4d506",
                      AirbridgeAttribute.PRODUCT_NAME: "MusicStreamingMemebership",
                      AirbridgeAttribute.PRODUCT_PRICE: 15,
                      AirbridgeAttribute.PRODUCT_CURRENCY: "USD"
                  ],
              ],
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.START_TRIAL semanticAttributes:@{
          AirbridgeAttribute.TRANSACTION_ID: @"ef1e5271-0370-407c-b1e9-669a8df1dc2c",
          AirbridgeAttribute.CURRENCY: @"USD",
          AirbridgeAttribute.PERIOD: @"P1M",
          AirbridgeAttribute.PRODUCTS: @[
              @{
                  AirbridgeAttribute.PRODUCT_ID: @"306a57cb-f653-4220-a208-8405d8e4d506",
                  AirbridgeAttribute.PRODUCT_NAME: @"MusicStreamingMemebership",
                  AirbridgeAttribute.PRODUCT_PRICE: @(15),
                  AirbridgeAttribute.PRODUCT_CURRENCY: @"USD"
              },
          ],
      }];
      ```
    </CodeGroup>

    ###### 구독

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.SUBSCRIBE, 
          semanticAttributes: [
              AirbridgeAttribute.VALUE: 15,
              AirbridgeAttribute.CURRENCY: "USD",
              AirbridgeAttribute.TRANSACTION_ID: "cbe718c7-e44e-4707-b5cd-4a6a29f29649",
              AirbridgeAttribute.PERIOD: "P1M",
              AirbridgeAttribute.IS_RENEWAL: true,
              AirbridgeAttribute.PRODUCTS: [
                  [
                      AirbridgeAttribute.PRODUCT_ID: "306a57cb-f653-4220-a208-8405d8e4d506",
                      AirbridgeAttribute.PRODUCT_NAME: "MusicStreamingMemebership",
                      AirbridgeAttribute.PRODUCT_PRICE: 15,
                      AirbridgeAttribute.PRODUCT_CURRENCY: "USD"
                  ],
              ]
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.SUBSCRIBE semanticAttributes:@{
          AirbridgeAttribute.VALUE: @(15),
          AirbridgeAttribute.CURRENCY: @"USD",
          AirbridgeAttribute.TRANSACTION_ID: @"cbe718c7-e44e-4707-b5cd-4a6a29f29649",
          AirbridgeAttribute.PERIOD: @"P1M",
          AirbridgeAttribute.IS_RENEWAL: @(YES),
          AirbridgeAttribute.PRODUCTS: @[
              @{
                  AirbridgeAttribute.PRODUCT_ID: @"306a57cb-f653-4220-a208-8405d8e4d506",
                  AirbridgeAttribute.PRODUCT_NAME: @"MusicStreamingMemebership",
                  AirbridgeAttribute.PRODUCT_PRICE: @(15),
                  AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
              },
          ],
      }];
      ```
    </CodeGroup>

    ###### 구독 취소

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.UNSUBSCRIBE, 
          semanticAttributes: [
              AirbridgeAttribute.VALUE: 15,
              AirbridgeAttribute.CURRENCY: "USD",
              AirbridgeAttribute.TRANSACTION_ID: "cbe718c7-e44e-4707-b5cd-4a6a29f29649",
              AirbridgeAttribute.IS_RENEWAL: true,
              AirbridgeAttribute.PRODUCTS: [
                  [
                      AirbridgeAttribute.PRODUCT_ID: "306a57cb-f653-4220-a208-8405d8e4d506",
                      AirbridgeAttribute.PRODUCT_NAME: "MusicStreamingMemebership",
                      AirbridgeAttribute.PRODUCT_PRICE: 15,
                      AirbridgeAttribute.PRODUCT_CURRENCY: "USD"
                  ]
              ]
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.UNSUBSCRIBE semanticAttributes:@{
          AirbridgeAttribute.VALUE: @(15),
          AirbridgeAttribute.CURRENCY: @"USD",
          AirbridgeAttribute.TRANSACTION_ID: @"cbe718c7-e44e-4707-b5cd-4a6a29f29649",
          AirbridgeAttribute.IS_RENEWAL: @(YES),
          AirbridgeAttribute.PRODUCTS: @[
              @{
                  AirbridgeAttribute.PRODUCT_ID: @"306a57cb-f653-4220-a208-8405d8e4d506",
                  AirbridgeAttribute.PRODUCT_NAME: @"MusicStreamingMemebership",
                  AirbridgeAttribute.PRODUCT_PRICE: @(15),
                  AirbridgeAttribute.PRODUCT_CURRENCY: @"USD"
              }
          ]
      }];
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="광고 노출, 광고 클릭, 튜토리얼 완료, 레벨 달성, 과제 달성">
    ###### 광고 노출

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.AD_IMPRESSION, 
          semanticAttributes: [
              AirbridgeAttribute.VALUE: 0.01,
              AirbridgeAttribute.AD_PARTNERS: [
                  "mopub": [
                      "app_version": "5.18.0",
                      "adunit_id": "12345",
                      "adunit_name": "12345",
                      "adunit_format": "Banner",
                      "id": "12345",
                      "currency": "USD",
                      "publisher_revenue": 12345.123,
                      "adgroup_id": "12345",
                      "adgroup_name": "12345",
                      "adgroup_type": "12345",
                      "adgroup_priority": "12345",
                      "country": "kr",
                      "precision": "publisher_defined",
                      "network_name": "12345",
                      "network_placement_id": "12345",
                      "demand_partner_data": "12345",
                  ]
              ]
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.AD_IMPRESSION semanticAttributes:@{
          AirbridgeAttribute.VALUE: @(0.01),
          AirbridgeAttribute.AD_PARTNERS: @{
              @"mopub": @{
                  @"app_version": @"5.18.0",
                  @"adunit_id": @"12345",
                  @"adunit_name": @"12345",
                  @"adunit_format": @"Banner",
                  @"id": @"12345",
                  @"currency": @"USD",
                  @"publisher_revenue": @(12345.123),
                  @"adgroup_id": @"12345",
                  @"adgroup_name": @"12345",
                  @"adgroup_type": @"12345",
                  @"adgroup_priority": @"12345",
                  @"country": @"kr",
                  @"precision": @"publisher_defined",
                  @"network_name": @"12345",
                  @"network_placement_id": @"12345",
                  @"demand_partner_data": @"12345",
              }
          }
      }];
      ```
    </CodeGroup>

    ###### 광고 클릭

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.AD_CLICK, 
          semanticAttributes: [
              AirbridgeAttribute.VALUE: 0.1,
              AirbridgeAttribute.AD_PARTNERS: [
                  "mopub": [
                      "app_version": "5.18.0",
                      "adunit_id": "12345",
                      "adunit_name": "12345",
                      "adunit_format": "Banner",
                      "id": "12345",
                      "currency": "USD",
                      "publisher_revenue": 12345.123,
                      "adgroup_id": "12345",
                      "adgroup_name": "12345",
                      "adgroup_type": "12345",
                      "adgroup_priority": "12345",
                      "country": "kr",
                      "precision": "publisher_defined",
                      "network_name": "12345",
                      "network_placement_id": "12345",
                      "demand_partner_data": "12345",
                  ]
              ]
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.AD_CLICK semanticAttributes:@{
          AirbridgeAttribute.VALUE: @(0.1),
          AirbridgeAttribute.AD_PARTNERS: @{
              @"mopub": @{
                  @"app_version": @"5.18.0",
                  @"adunit_id": @"12345",
                  @"adunit_name": @"12345",
                  @"adunit_format": @"Banner",
                  @"id": @"12345",
                  @"currency": @"USD",
                  @"publisher_revenue": @(12345.123),
                  @"adgroup_id": @"12345",
                  @"adgroup_name": @"12345",
                  @"adgroup_type": @"12345",
                  @"adgroup_priority": @"12345",
                  @"country": @"kr",
                  @"precision": @"publisher_defined",
                  @"network_name": @"12345",
                  @"network_placement_id": @"12345",
                  @"demand_partner_data": @"12345",
              }
          }
      }];
      ```
    </CodeGroup>

    ###### 튜토리얼 완료

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.COMPLETE_TUTORIAL, 
          semanticAttributes: [
              AirbridgeAttribute.DESCRIPTION: "Finish Initial Tutorial",
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.COMPLETE_TUTORIAL semanticAttributes:@{
          AirbridgeAttribute.DESCRIPTION: @"Finish Initial Tutorial",
      }];
      ```
    </CodeGroup>

    ###### 레벨 달성

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.ACHIEVE_LEVEL, 
          semanticAttributes: [
              AirbridgeAttribute.LEVEL: 13,
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.ACHIEVE_LEVEL semanticAttributes:@{
          AirbridgeAttribute.LEVEL: @(13),
      }];
      ```
    </CodeGroup>

    ###### 과제 달성

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.UNLOCK_ACHIEVEMENT, 
          semanticAttributes: [
              AirbridgeAttribute.ACHIEVEMENT_ID: "36a0f0bb-b153-4be1-a3e0-3cb5b2b076c1",
              AirbridgeAttribute.DESCRIPTION: "Get Score Over 50",
              AirbridgeAttribute.SCORE: 80,
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.UNLOCK_ACHIEVEMENT semanticAttributes:@{
          AirbridgeAttribute.ACHIEVEMENT_ID: @"36a0f0bb-b153-4be1-a3e0-3cb5b2b076c1",
          AirbridgeAttribute.DESCRIPTION: @"Get Score Over 50",
          AirbridgeAttribute.SCORE: @(80),
      }];
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="평가, 공유, 일정 예약, 크레딧 사용">
    ###### 평가

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.RATE, 
          semanticAttributes: [
              AirbridgeAttribute.RATE_ID: "531c64b3-4704-4780-a306-89014ec18daf",
              AirbridgeAttribute.RATE: 4.5,
              AirbridgeAttribute.MAX_RATE: 5,
              AirbridgeAttribute.PRODUCTS: [
                  [
                      AirbridgeAttribute.PRODUCT_ID: "0117b32a-5a6c-4d4c-b64c-7858e07dba78",
                      AirbridgeAttribute.PRODUCT_NAME: "PlasticHammer",
                      AirbridgeAttribute.PRODUCT_PRICE: 10,
                      AirbridgeAttribute.PRODUCT_CURRENCY: "USD",
                  ],
              ],
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.RATE semanticAttributes:@{
          AirbridgeAttribute.RATE_ID: @"531c64b3-4704-4780-a306-89014ec18daf",
          AirbridgeAttribute.RATE: @(4.5),
          AirbridgeAttribute.MAX_RATE: @(5),
          AirbridgeAttribute.PRODUCTS: @[
              @{
                  AirbridgeAttribute.PRODUCT_ID: @"0117b32a-5a6c-4d4c-b64c-7858e07dba78",
                  AirbridgeAttribute.PRODUCT_NAME: @"PlasticHammer",
                  AirbridgeAttribute.PRODUCT_PRICE: @(10),
                  AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
              },
          ],
      }];
      ```
    </CodeGroup>

    ###### 공유

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.SHARE, 
          semanticAttributes: [
              AirbridgeAttribute.DESCRIPTION: "Share Promotion",
              AirbridgeAttribute.SHARED_CHANNEL: "CopyLink",
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.SHARE semanticAttributes:@{
          AirbridgeAttribute.DESCRIPTION: @"Share Promotion",
          AirbridgeAttribute.SHARED_CHANNEL: @"CopyLink",
      }];
      ```
    </CodeGroup>

    ###### 일정 예약

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.SCHEDULE, 
          semanticAttributes: [
              AirbridgeAttribute.SCHEDULE_ID: "75712915-2cd9-4e42-a85e-8d42f356f4c6",
              AirbridgeAttribute.DATE_TIME: "2024-01-01T00:00:00+00:00",
              AirbridgeAttribute.PLACE: "ConferenceRoom",
              AirbridgeAttribute.PRODUCTS: [
                  [
                      AirbridgeAttribute.PRODUCT_ID: "abb3e65d-17bc-4b28-89e3-5e356c0ea697",
                      AirbridgeAttribute.PRODUCT_NAME: "ConferenceRoom",
                  ],
              ],
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.SCHEDULE semanticAttributes:@{
          AirbridgeAttribute.SCHEDULE_ID: @"75712915-2cd9-4e42-a85e-8d42f356f4c6",
          AirbridgeAttribute.DATE_TIME: @"2024-01-01T00:00:00+00:00",
          AirbridgeAttribute.PLACE: @"ConferenceRoom",
          AirbridgeAttribute.PRODUCTS: @[
              @{
                  AirbridgeAttribute.PRODUCT_ID: @"abb3e65d-17bc-4b28-89e3-5e356c0ea697",
                  AirbridgeAttribute.PRODUCT_NAME: @"ConferenceRoom",
              },
          ],
      }];
      ```
    </CodeGroup>

    ###### 크레딧 사용

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      Airbridge.trackEvent(
          category: AirbridgeCategory.SPEND_CREDITS, 
          semanticAttributes: [
              AirbridgeAttribute.TRANSACTION_ID: "22eb193d-be11-4fe4-95da-c91a196faf1c",
              AirbridgeAttribute.PRODUCT_CURRENCY: "USD",
              AirbridgeAttribute.PRODUCTS: [
                  [
                      AirbridgeAttribute.PRODUCT_ID: "0117b32a-5a6c-4d4c-b64c-7858e07dba78",
                      AirbridgeAttribute.PRODUCT_NAME: "PlasticHammer",
                      AirbridgeAttribute.PRODUCT_PRICE: 10,
                      AirbridgeAttribute.PRODUCT_CURRENCY: "USD"
                  ]
              ]
          ]
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>
      ...
      [Airbridge trackEventWithCategory:AirbridgeCategory.SPEND_CREDITS semanticAttributes:@{
          AirbridgeAttribute.TRANSACTION_ID: @"22eb193d-be11-4fe4-95da-c91a196faf1c",
          AirbridgeAttribute.PRODUCT_CURRENCY: @"USD",
          AirbridgeAttribute.PRODUCTS: @[
              @{
                  AirbridgeAttribute.PRODUCT_ID: @"0117b32a-5a6c-4d4c-b64c-7858e07dba78",
                  AirbridgeAttribute.PRODUCT_NAME: @"PlasticHammer",
                  AirbridgeAttribute.PRODUCT_PRICE: @(10),
                  AirbridgeAttribute.PRODUCT_CURRENCY: @"USD"
              }
          ]
      }];
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

커스텀 이벤트는 앱 서비스에 맞는 광고 성과를 추적하기 위해 스탠다드 이벤트에 해당하지 않는 유저의 행동을 새로 정의한 이벤트입니다. 아래 예시 코드를 참고해 주세요.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  Airbridge.trackEvent(
      category: "event",
      semanticAttributes: [
          AirbridgeAttribute.VALUE: 10,
      ],
      customAttributes: [
          "string": "string",
          "number": 1000,
          "boolean": true,
          "object": ["key": "value"],
          "array": ["value"],
      ]
  )
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>
  ...
  [Airbridge trackEventWithCategory:@"event" semanticAttributes:@{
      AirbridgeAttribute.VALUE: @(10),
  } customAttributes:@{
      @"string": "string",
      @"number": @(1000),
      @"boolean": @(YES),
      @"object": @{@"key": @"value"},
      @"array": @[@"value"],
      @"key": @"value",
  }];
  ```
</CodeGroup>

## 유저 정보

유저 정보를 이벤트 포함해 전송합니다. 해당 유저 정보를 바탕으로 웹과 앱에서 발생한 광고 성과를 더 정확하게 분석할 수 있습니다.

### 유저 ID 설정하기

유저 ID는 서비스에서 활용하는 유저 식별자입니다. 유저 ID는 유저를 웹과 앱에서 하나의 유저로 특정할 수 있는 고유한 ID이어야 합니다.

| <span style={{ display: 'inline-block', minWidth: '140px' }}>함수</span> | <span style={{ display: 'inline-block', minWidth: '240px' }}>설명</span>                                                             |
| ---------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `Airbridge.setUserID`                                                  | 유저 ID를 입력합니다.                                                                                                                      |
| `Airbridge.clearUserID`                                                | 유저 ID를 삭제합니다.                                                                                                                      |
| `Airbridge.setUserAlias`                                               | 유저 식별자를 추가로 입력합니다. 최대 10개 입력할 수 있습니다.<br />- key: 최대 128자입니다. `^[a-zA-Z_][a-zA-Z0-9_]*$` 정규식을 만족해야 합니다.<br />- value: 최대 1024자입니다. |
| `Airbridge.removeUserAlias`                                            | 추가로 입력한 유저 식별자 중에서 지정한 식별자를 삭제합니다.                                                                                                 |
| `Airbridge.clearUserAlias`                                             | 추가로 입력한 모든 유저 식별자를 삭제합니다.                                                                                                          |

아래 예시를 참고해 주세요.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  // identifier
  Airbridge.setUserID("string")
  Airbridge.clearUserID()
  // addtional identifier
  Airbridge.setUserAlias(key: "string", value: "string")
  Airbridge.removeUserAlias(key: "string")
  Airbridge.clearUserAlias()
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>
  ...
  // identifier
  [Airbridge setUserID:@"string"];
  [Airbridge clearUserID];
  // additional identifier
  [Airbridge setUserAliasWithKey:@"string" value:@"string"];
  [Airbridge removeUserAliasWithKey:@"string"];
  [Airbridge clearUserAlias];
  ```
</CodeGroup>

### 유저 속성 설정하기

<Danger>
  **주의하세요**

  민감한 유저 정보가 포함될 수 있습니다. 법률 자문사와 충분히 검토한 후에 전송해 주세요.
</Danger>

유저 속성을 설정하면 추가 유저 정보를 전송할 수 있습니다.

| <span style={{ display: 'inline-block', minWidth: '140px' }}>함수</span> | <span style={{ display: 'inline-block', minWidth: '240px' }}>설명</span>                                                                                                |
| ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Airbridge.setUserEmail`                                               | 유저 이메일을 입력합니다. SHA256으로 해시(Hash)화되어 있습니다.                                                                                                                             |
| `Airbridge.clearUserEmail`                                             | 유저 이메일을 삭제합니다.                                                                                                                                                        |
| `Airbridge.setUserPhone`                                               | 유저 전화 번호를 입력합니다. SHA256으로 해시화되어 있습니다.                                                                                                                                 |
| `Airbridge.clearUserPhone`                                             | 유저 전화 번호를 삭제합니다.                                                                                                                                                      |
| `Airbridge.setUserAttribute`                                           | 유저 속성을 추가로 입력합니다. 최대 100개 입력할 수 있습니다.<br />- key: 최대 128자입니다. `^[a-zA-Z_][a-zA-Z0-9_]*$` 정규식을 만족해야 합니다.<br />- value: String, Number, Boolean 타입만 지원합니다. 최대 1024자입니다. |
| `Airbridge.removeUserAttribute`                                        | 추가로 입력한 유저 속성 중에서 지정한 속성을 삭제합니다.                                                                                                                                      |
| `Airbridge.clearUserAttributes`                                        | 추가로 입력한 모든 유저 속성을 삭제합니다.                                                                                                                                              |

아래 예시를 참고해 주세요.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  // 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()
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>
  ...
  // 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];
  ```
</CodeGroup>

`Airbridge.setHashUserInformationEnabled` 함수를 false로 설정하면 유저 이메일과 전화번호를 해시화하지 않고 전송합니다. 기본 설정은 true입니다.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
      .setHashUserInformationEnabled(false)
      .build()
  Airbridge.initializeSDK(option: option)
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>
  ...
  AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                 token:@"YOUR_APP_SDK_TOKEN"];
  [optionBuilder setHashUserInformationEnabled:NO];
  AirbridgeOption* option = [optionBuilder build];
  [Airbridge initializeSDKWithOption:option];
  ```
</CodeGroup>

### 유저 정보 초기화하기

`Airbridge.clearUser` 함수로 유저 정보를 초기화할 수 있습니다.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  Airbridge.clearUser()
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>
  ...
  [Airbridge clearUser];
  ```
</CodeGroup>

### 설치/오픈 이벤트에 유저 정보 포함하기

SDK는 초기화 직후 설치 및 오픈 이벤트를 자동으로 전송합니다. 따라서 초기화 직후 유저 정보 함수를 호출하면, 이벤트 전송 타이밍에 따라 유저 정보가 설치/오픈 이벤트에 포함되지 않을 수 있습니다.

설치/오픈 이벤트에 유저 정보를 확실히 포함하려면, [옵트인(Opt-In) 설정하기](#옵트인-opt-in-설정하기)를 통해 이벤트 전송 시점을 제어하세요.

다음 순서로 구현하세요:

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  // 1. initialize SDK. Opt-in setup
  let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
      .setAutoStartTrackingEnabled(false)
      .build()
  Airbridge.initializeSDK(option: option)

  // 2. Set up user data
  Airbridge.setUserID("testID")
  Airbridge.setUserEmail("testID@ab180.co")

  // 3. Explicitly start tracking
  Airbridge.startTracking()
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  // 1. initialize SDK. Opt-in setup
  AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                 token:@"YOUR_APP_SDK_TOKEN"];
  [optionBuilder setAutoStartTrackingEnabled:NO];
  AirbridgeOption* option = [optionBuilder build];
  [Airbridge initializeSDKWithOption:option];

  // 2. Set up user data
  [Airbridge setUserID:@"testID"];
  [Airbridge setUserEmail:@"testID@ab180.co"];

  // 3. Explicitly start tracking
  [Airbridge startTracking];
  ```
</CodeGroup>

## 추가 설정하기

iOS SDK를 추가로 설정할 수 있습니다.

<Info>
  **알립니다**

  필수 설정 기능이 아닙니다. 필요한 경우에만 설정해 주세요.
</Info>

### 멀티 앱 사용하기

<Info>
  **알립니다**

  에어브릿지 iOS SDK 4.9.0 이상이 필요합니다.
</Info>

기본적으로 SDK는 전역 `Airbridge` 객체를 통해 제어됩니다. 하지만 특정 상황에서는 독립적인 SDK 인스턴스가 필요할 수 있습니다. SDK는 하나의 앱에서 여러 Airbridge 프로젝트를 동시에 운영하는 멀티 테넌트 환경을 지원합니다.

`AirbridgeInterface`를 사용하여 새로운 인스턴스를 생성할 수 있습니다.

#### **인스턴스 생성 및 초기화**

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge

  final public class CustomInstance: AirbridgeInterface {}

  CustomInstance.initializeSDK(
      option: AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_TOKEN").build()
  )
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  // Bridging .swift
  import Airbridge

  final public class CustomInstance: AirbridgeInterface {}

  // Implements .m
  AirbridgeOptionBuilder *optionBuilder = [
      [AirbridgeOptionBuilder alloc]
      initWithName:@"YOUR_APP_NAME"
      token:@"YOUR_APP_NAME"
  ];
  [CustomInstnce initializeSDKWithOption:[optionBuilder build]];
  ```
</CodeGroup>

각 인스턴스는 전역 `Airbridge` 객체 및 다른 인스턴스와 완전히 독립적으로 동작하며, 초기화를 포함한 모든 SDK 기능을 독립적으로 사용할 수 있습니다.

<Danger>
  **SKAdNetwork 식별자 제한 주의사항**

  멀티 앱 환경에서는 **단 하나의 인스턴스**에서만 SKAdNetwork 관련 식별자를 허용해야 합니다.

  SKAdNetwork를 여러 인스턴스에서 허용할 경우, 중복된 전환 데이터로 인해 SKAdNetwork 어트리뷰션이 제대로 작동하지 않을 수 있습니다.

  자세한 내용은 [식별자 추적 제한하기](#sdk-초기화시-식별자-제한하기)를 참고하세요.
</Danger>

#### **이벤트 전달 예제**

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  CustomInstnce.trackEvent(
      category: "event",
      semanticAttributes: [
          AirbridgeAttribute.VALUE: 10,
      ],
      customAttributes: [
          "string": "string",
          "number": 1000,
          "boolean": true,
          "object": ["key": "value"],
          "array": ["value"],
      ]
  )
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  [CustomInstnce trackEventWithCategory:@"event" semanticAttributes:@{
      AirbridgeAttribute.VALUE: @(10),
  } customAttributes:@{
      @"string": @"string",
      @"number": @(1000),
      @"boolean": @(YES),
      @"object": @{@"key": @"value"},
      @"array": @[@"value"],
      @"key": @"value",
  }];
  ```
</CodeGroup>

### 멀티 앱 디퍼드 딥링크 사용하기

<Note>
  **알립니다**

  에어브릿지 iOS SDK 4.10.0 이상이 필요합니다.
</Note>

멀티 앱 환경에서 디퍼드 딥링크를 수신하려면 `Airbridge.handleDeferredDeeplink(apps:onSuccess:onFailure)` 함수를 사용해야 합니다.

기존의 `Airbridge.handleDeferredDeeplink(onSuccess:onFailure)` 함수는 멀티 앱 환경에서 각 인스턴스가 클릭한 트래킹 링크의 디퍼드 딥링크를 중복으로 수신할 수 있습니다. 이로 인해 `onSuccess` 콜백이 중복 호출되어 화면 이동에 문제가 발생할 수 있습니다.

`Airbridge.handleDeferredDeeplink(apps:onSuccess:onFailure)` 함수는 `apps`로 전달된 에어브릿지 인스턴스 목록 중 가장 최근에 클릭한 트래킹 링크의 디퍼드 딥링크 정보만을 콜백으로 전달합니다. 디퍼드 딥링크는 앱에서 단 한 번만 전달됩니다.

<Danger>
  **주의하세요.**

  멀티 앱 환경에서는 `Airbridge.handleDeferredDeeplink(onSuccess:onFailure)` 대신 반드시 `Airbridge.handleDeferredDeeplink(apps:onSuccess:onFailure)` 함수를 사용해 주세요
</Danger>

디퍼드 딥링크 획득 방식은 [디퍼드 딥링크 처리하기](https://app.notion.com/p/ab180/25aa69a82507809b9712f82ae535ec14?v=280a69a8250780eda460000c0ff7b132\&p=365a69a825078025b621e530f516c7c0\&pm=s#)를 참고해 주세요.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
      .build()
  CustomInstance1.initializeSDK(option: option)
  ...
  let canHandle = CustomInstance1.handleDeferredDeeplink(apps: [CustomInstance1, CustomInstance2]) { url in
      // when handleDeferredDeeplink is called firstly after install
      if let url {
          // show proper content using url (YOUR_SCHEME://...)
      }
  }
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #incldue <
  AirbridgeOptionBuilder *optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME" token:@"YOUR_APP_SDK_TOKEN"];
  [CustomInstance1 initializeSDKWithOption:[optionBuilder build]];

  bool canHandle = [CustomInstance1 handleDeferredDeeplinkWithApps:@[CustomInstance1.class, CustomInstance2.class] onSuccess:^(NSURL * _Nullable url) {
      // when handleDeferredDeeplink is called firstly after install
      if (url != nil) {
          // show proper content using url (YOUR_SCHEME://...)
      }
  }];
  ```
</CodeGroup>

### SKAdNetwork ConversionValue 계산을 서버에서 하기

<Info>
  **알립니다**

  에어브릿지 iOS SDK 4.8.0 이상이 필요합니다.
</Info>

SKAdNetwork의 ConversionValue는 기본적으로 SDK에서 계산한 값을 사용하고 있습니다. SDK가 아닌 서버 사이드로 수집한 이벤트를 SKAN으로 측정하고자 한다면 `calculateSKAdNetworkByServerEnabled` 옵션값을 `true`로 변경 해 주세요.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge

  let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
      .setCalculateSKAdNetworkByServerEnabled(true or false)
      .build()
      
  Airbridge.initializeSDK(option: option)
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>
  ...
  AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                 token:@"YOUR_APP_SDK_TOKEN"];
  [optionBuilder setCalculateSKAdNetworkByServerEnabled:YES or NO];

  AirbridgeOption* option = [optionBuilder build];
  [Airbridge initializeSDKWithOption:option];
  ```
</CodeGroup>

<Danger>
  **알립니다**

  이미 SKAdNetwork 전환값을 SDK 에서 계산한 값을 사용중이시면 변경시 주의 바랍니다. 전환값 계산 방식을 변경할 경우, 기존 데이터와 새로운 데이터 간의 일관성 문제가 발생할 수 있습니다.
</Danger>

### 식별자 추적 제한하기

SDK가 식별자 데이터를 추적하지 않도록 제한할 수 있습니다.

<AccordionGroup>
  <Accordion title="SDK 초기화시 식별자 제한하기">
    <Info>
      **알립니다**

      에어브릿지 iOS SDK 4.7.0 이상이 필요합니다.
    </Info>

    SDK 초기화시 `setTrackingBlocklist` 함수에 제한할 데이터들을 설정하면 수집되는 이벤트에서 지정된 식별자 항목들이 제외됩니다. 이미 저장된 이벤트에는 영향이 없습니다.

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge

      let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
          .setTrackingBlocklist([
                .idfa,
                .idfv,
            ])
          .build()
      Airbridge.initializeSDK(option: option)
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #import <Airbridge/Airbridge.h>

      AirbridgeOptionBuilder *builder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME" token:@"YOUR_APP_SDK_TOKEN"];
      [builder setTrackingBlocklist:@[
          AirbridgeTrackingBlocklist.idfa,
          AirbridgeTrackingBlocklist.idfv
      ]];
          
      [Airbridge initializeSDKWithOption:[builder build]];
      ```
    </CodeGroup>

    [식별자 제한 목록](#식별자-제한-목록)에서 제한 가능한 데이터에 대해서 확인하세요.
  </Accordion>

  <Accordion title="SDK 동작 중 식별자 제한하기">
    <Info>
      **알립니다**

      에어브릿지 iOS SDK 4.9.0 이상이 필요합니다.
    </Info>

    SDK 동작 중 `allowTrackingItem`, `blockTrackingItem` 함수를 사용하여 제한할 데이터들을 설정할 수 있습니다. 지정된 식별자 항목들은 제외 혹은 포함됩니다. 이미 저장된 이벤트에는 영향이 없습니다.

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      static func allowTrackingItem(
          _ item: AirbridgeTrackingBlocklist
      )

      static func blockTrackingItem(
          _ item: AirbridgeTrackingBlocklist
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      + (void)allowTrackingItem:(AirbridgeTrackingBlocklist)item
      + (void)blockTrackingItem:(AirbridgeTrackingBlocklist)item
      ```
    </CodeGroup>

    [식별자 제한 목록](#식별자-제한-목록)에서 제한 가능한 데이터에 대해서 확인하세요.
  </Accordion>

  <Accordion title="식별자 제한 목록">
    | 식별자         | 지원버전  | 설명                                                                                                                                           |
    | ----------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------------- |
    | idfa        | 4.7.0 | IDFA 의 수집을 제한합니다.                                                                                                                            |
    | idfv        | 4.7.0 | IDFV 의 수집을 제한합니다.                                                                                                                            |
    | skAdNetwork | 4.9.0 | SKAdNetwork 의 수집을 제한합니다. SKAdNetwork 계산이 수행되더라도 SKAdNetwork 값을 업데이트 하지 않습니다.<br />멀티 앱 환경에서는 **단 하나의 인스턴스**에서만 SKAdNetwork 관련 식별자를 허용해야 합니다. |
  </Accordion>
</AccordionGroup>

### ICM 어트리뷰션 데이터 확인하기

<Info>
  **알립니다**

  에어브릿지 iOS SDK 4.4.1 이상이 필요합니다.
</Info>

구글 애즈는 개인정보 수집에 동의하지 않은 유저의 디바이스에서 발생한 전환에 대해 ICM(Integrated Conversion Measurement) 어트리뷰션 데이터를 제공합니다. [ICM](https://support.google.com/google-ads/answer/16203286)은 구글 애즈에서 개인정보보호 기반 전환 모델링으로 유저를 식별하지 않고 성과를 측정하는 방법입니다.

ICM 어트리뷰션 데이터를 확인하려면 구글의 ODM(On-Device Conversion Measurement) SDK를 설치하고 에어브릿지의 iOS SDK 버전을 4.4.1 이상으로 업데이트해야 합니다. ODM SDK 설치는 [구글 가이드](https://support.google.com/google-ads/answer/16384720)를 참고해 주세요.

### 인앱에서 트래킹 링크 생성하기

<Info>
  **알립니다**

  에어브릿지 iOS SDK 4.3.0 이상이 필요합니다.
</Info>

트래킹 링크는 유저가 발생시킨 터치포인트 데이터를 에어브릿지에 전달하기 위해 만드는 링크입니다.

트래킹 링크를 활용하면 광고를 보거나 클릭한 유저를 원하는 목적지로 보낼 수 있습니다. 에어브릿지는 트래킹 링크로 수집한 터치포인트 데이터를 활용해 전환에 기여한 채널을 분석할 수 있습니다.

트래킹 링크 생성을 하기 위해서는 `createTrackingLink` 함수를 사용합니다. 파라미터의 필수 여부와 타입은 아래와 같습니다.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  public static func createTrackingLink(
      channel: String,
      option: [String: Any],
      onSuccess: @escaping (AirbridgeTrackingLink) -> Void
  )

  public static func createTrackingLink(
      channel: String,
      option: [String: Any],
      onSuccess: @escaping (AirbridgeTrackingLink) -> Void,
      onFailure: @escaping (Error) -> Void
  )
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  + (void)createTrackingLinkWithChannel:(NSString*)channel
                                 option:(NSDictionary<NSString*, id>*)option
                              onSuccess:(void (^)(AirbridgeTrackingLink*))onSuccess;
  + (void)createTrackingLinkWithChannel:(NSString*)channel
                                 option:(NSDictionary<NSString*, id>*)option
                              onSuccess:(void (^)(AirbridgeTrackingLink*))onSuccess
                              onFailure:(void (^)(NSError*))onFailure;
  ```
</CodeGroup>

| 이름        | 필수 여부 | 타입                              | 설명                |
| --------- | ----- | ------------------------------- | ----------------- |
| channel   | 필수    | String                          | 트래킹 링크를 사용할 광고 채널 |
| option    | 필수    | \[String: Any]                  | 트래킹 링크 생성 옵션      |
| onSuccess | 필수    | (AirbridgeTrackingLink) -> Void | 성공 콜백             |
| onFailure | 선택    | (Error) -> Void                 | 실패 콜백             |

`createTrackingLink` 함수는 `option` 파라미터를 통해 생성 옵션을 설정할 수 있습니다.

<Accordion title="트래킹 링크 생성 옵션">
  | 키                                                             | 타입                                   | 설명                                                                                                                                                                                                                        |
  | ------------------------------------------------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | AirbridgeTrackingLinkOption.CAMPAIGN                          | String                               | 캠페인 이름                                                                                                                                                                                                                    |
  | AirbridgeTrackingLinkOption.AD\_GROUP                         | String                               | 광고 그룹                                                                                                                                                                                                                     |
  | AirbridgeTrackingLinkOption.AD\_CREATIVE                      | String                               | 광고 소재                                                                                                                                                                                                                     |
  | AirbridgeTrackingLinkOption.CONTENT                           | String                               | 광고 콘텐츠                                                                                                                                                                                                                    |
  | AirbridgeTrackingLinkOption.TERM                              | String                               | 검색 광고 키워드                                                                                                                                                                                                                 |
  | AirbridgeTrackingLinkOption.SUB\_ID                           | String                               | 하위 네트워크 혹은 제휴 매체사 등을 나타내는 아이디.                                                                                                                                                                                            |
  | AirbridgeTrackingLinkOption.SUB\_ID\_1                        | String                               | 하위 네트워크 또다른 하위 네트워크 아이디(sub-sub publisher). 하위 매체 순서(계층)에 맞게 사용해야합니다 (sub\_id\_1 > sub\_id\_2 > sub\_id\_3)                                                                                                               |
  | AirbridgeTrackingLinkOption.SUB\_ID\_2                        | String                               | 하위 네트워크 또다른 하위 네트워크 아이디(sub-sub publisher). 하위 매체 순서(계층)에 맞게 사용해야합니다 (sub\_id\_1 > sub\_id\_2 > sub\_id\_3)                                                                                                               |
  | AirbridgeTrackingLinkOption.SUB\_ID\_3                        | String                               | 하위 네트워크 또다른 하위 네트워크 아이디 (sub-sub publisher). 하위 매체 순서(계층)에 맞게 사용해야합니다 (sub\_id\_1 > sub\_id\_2 > sub\_id\_3)                                                                                                              |
  | AirbridgeTrackingLinkOption.DEEPLINK\_URL                     | (Custom Scheme URL String)           | Deeplink URL                                                                                                                                                                                                              |
  | AirbridgeTrackingLinkOption.DEEPLINK\_STOPOVER                | Bool                                 | Deeplink 의 스탑오버 기능 활성화 여부<br />true : 활성화<br />false : 비활성화                                                                                                                                                               |
  | AirbridgeTrackingLinkOption.FALLBACK\_IOS                     | ("store" \| Web URL String)          | App 미설치시 ios fallback                                                                                                                                                                                                     |
  | AirbridgeTrackingLinkOption.FALLBACK\_ANDROID                 | ("store" \| Web URL String)          | App 미설치시 android fallback                                                                                                                                                                                                 |
  | AirbridgeTrackingLinkOption.FALLBACK\_DESKTOP                 | (Web URL String)                     | App 미설치시 desktop fallback                                                                                                                                                                                                 |
  | AirbridgeTrackingLinkOption.FALLBACK\_IOS\_STORE\_PPID        | String                               | 애플 앱 스토어의 맞춤형 제품 페이지(Custom Product Page)의 ppid.<br />앱 스토어로 랜딩할 경우 맞춤형 제품 페이지를 보여줄 수 있도록 설정합니다.                                                                                                                          |
  | AirbridgeTrackingLinkOption.FALLBACK\_ANDROID\_STORE\_LISTING | String                               | 구글 플레이 스토어의 맞춤 스토어 등록정보(Custom Store Listing) listing 값.<br />구글 플레이 스토어로 랜딩할 경우 맞춤 스토어 등록정보를 보여줄 수 있도록 설정합니다.                                                                                                            |
  | AirbridgeTrackingLinkOption.OGTAG\_TITLE                      | String                               | 트래킹 링크의 og:title                                                                                                                                                                                                          |
  | AirbridgeTrackingLinkOption.OGTAG\_DESCRIPTION                | String                               | 트래킹 링크의 og:description                                                                                                                                                                                                    |
  | AirbridgeTrackingLinkOption.OGTAG\_IMAGE\_URL                 | (Web URL String)                     | 트래킹 링크의 og:image                                                                                                                                                                                                          |
  | AirbridgeTrackingLinkOption.OGTAG\_WEBSITE\_CRAWL             | ("desktop")                          | 트래킹 링크가 소셜 미디어에 공유될 때 소셜 미디어가 fallbackPaths에 지정된 desktop URL의 Open Graph 태그를 직접 크롤링해 소셜 쉐어 프리뷰에 사용합니다. 동적(Dynamic) URL도 지원하며, Open Graph 태그의 변경 사항은 다음 공유 시점부터 자동으로 반영됩니다. 이때 title, description, imageUrl로 설정한 값은 무시됩니다. |
  | AirbridgeTrackingLinkOption.CUSTOM\_SHORT\_ID                 | String                               | Custom 채널의 트래킹 링크 생성시 축약된 링크 숏 아이디. [커스텀 도메인](/ko/guides/custom-domain) 설정을 해야 사용할 수 있습니다.<br />입력하지 않으면 랜덤 아이디가 생성되며, 트래킹 링크 생성 완료 후에는 변경할 수 없습니다.                                                                       |
  | AirbridgeTrackingLinkOption.IS\_REENGAGEMENT                  | ("off" \| "on\_true" \| "on\_false") | re-engagement 파라미터.<br />off: 해당 트래킹 링크에 발생한 터치포인트로 설치 및 인앱 이벤트를 기여합니다.<br />on\_true: 딥링크 오픈 및 그에 기인한 이벤트만 기여됩니다. Re-engagement 캠페인에 활용 가능합니다.<br />on\_false: 설치 이벤트 및 그에 기인한 인앱 이벤트만 기여됩니다. UA 캠페인에 활용 가능합니다.          |
</Accordion>

`createTrackingLink` 함수는 `onSuccess` 콜백을 통해 `AirbridgeTrackingLink` 를 전달합니다.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  public final class AirbridgeTrackingLink: NSObject {
      public let shortURL: URL
      public let qrcodeURL: URL
  }
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  @interface AirbridgeTrackingLink : NSObject

  + (NSURL*)shortURL;
  + (NSURL*)qrcodeURL;

  @end
  ```
</CodeGroup>

| 이름        | 타입  | 설명                  |
| --------- | --- | ------------------- |
| shortURL  | URL | 트래킹 링크의 단축 URL      |
| qrcodeURL | URL | 트래킹 링크의 QR Code URL |

아래 예시 코드를 참고해 주세요.

<AccordionGroup>
  <Accordion title="앱이 열리거나 스토어로 이동하는 트래킹 링크 생성하기">
    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      Airbridge.createTrackingLink(
          channel: "test_channel",
          option: [
              AirbridgeTrackingLinkOption.CAMPAIGN: "test_campaign",
              AirbridgeTrackingLinkOption.DEEPLINK_URL: "YOUR_SCHEME://...",
              AirbridgeTrackingLinkOption.FALLBACK_IOS: "store",
              AirbridgeTrackingLinkOption.FALLBACK_ANDROID: "store",
              AirbridgeTrackingLinkOption.FALLBACK_DESKTOP: "https://example.com/"
          ],
          onSuccess: { trackingLink in
              // Handling created tracking-link
          },
          onFailure: { error in
              // Handling error
          }
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      [Airbridge createTrackingLinkWithChannel:@"test_channel" option:@{
          AirbridgeTrackingLinkOption.CAMPAIGN: @"test_campaign",
          AirbridgeTrackingLinkOption.DEEPLINK_URL: @"YOUR_SCHEME://...",
          AirbridgeTrackingLinkOption.FALLBACK_IOS: @"store",
          AirbridgeTrackingLinkOption.FALLBACK_ANDROID: @"store",
          AirbridgeTrackingLinkOption.FALLBACK_DESKTOP: @"https://example.com/"
      } onSuccess:^(AirbridgeTrackingLink* trackingLink) {
          // Handling created tracking-link
      } onFailure:^(NSError* error) {
          // Handling error
      }];
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="앱이 열리거나 웹페이지로 이동하는 트래킹 링크 생성">
    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      Airbridge.createTrackingLink(
          channel: "test_channel",
          option: [
              AirbridgeTrackingLinkOption.CAMPAIGN: "test_campaign",
              AirbridgeTrackingLinkOption.DEEPLINK_URL: "YOUR_SCHEME://...",
              AirbridgeTrackingLinkOption.FALLBACK_IOS: "https://example.com/",
              AirbridgeTrackingLinkOption.FALLBACK_ANDROID: "https://example.com/",
              AirbridgeTrackingLinkOption.FALLBACK_DESKTOP: "https://example.com/"
          ],
          onSuccess: { trackingLink in
              // Handling created tracking-link
          },
          onFailure: { error in
              // Handling error
          }
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      [Airbridge createTrackingLinkWithChannel:@"test_channel" option:@{
          AirbridgeTrackingLinkOption.CAMPAIGN: @"test_campaign",
          AirbridgeTrackingLinkOption.DEEPLINK_URL: @"YOUR_SCHEME://...",
          AirbridgeTrackingLinkOption.FALLBACK_IOS: @"https://example.com/",
          AirbridgeTrackingLinkOption.FALLBACK_ANDROID: @"https://example.com/",
          AirbridgeTrackingLinkOption.FALLBACK_DESKTOP: @"https://example.com/"
      } onSuccess:^(AirbridgeTrackingLink* trackingLink) {
          // Handling created tracking-link
      } onFailure:^(NSError* error) {
          // Handling error
      }];
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="스토어로만 이동하는 트래킹 링크 생성하기">
    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      Airbridge.createTrackingLink(
          channel: "test_channel",
          option: [
              AirbridgeTrackingLinkOption.CAMPAIGN: "test_campaign",
              AirbridgeTrackingLinkOption.FALLBACK_IOS: "store",
              AirbridgeTrackingLinkOption.FALLBACK_ANDROID: "store",
              AirbridgeTrackingLinkOption.FALLBACK_DESKTOP: "https://example.com/"
          ],
          onSuccess: { trackingLink in
              // Handling created tracking-link
          },
          onFailure: { error in
              // Handling error
          }
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      [Airbridge createTrackingLinkWithChannel:@"test_channel" option:@{
          AirbridgeTrackingLinkOption.CAMPAIGN: @"test_campaign",
          AirbridgeTrackingLinkOption.FALLBACK_IOS: @"store",
          AirbridgeTrackingLinkOption.FALLBACK_ANDROID: @"store",
          AirbridgeTrackingLinkOption.FALLBACK_DESKTOP: @"https://example.com/"
      } onSuccess:^(AirbridgeTrackingLink* trackingLink) {
          // Handling created tracking-link
      } onFailure:^(NSError* error) {
          // Handling error
      }];
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="웹페이지로만 이동하는 트래킹 링크 생성하기">
    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      Airbridge.createTrackingLink(
          channel: "test_channel",
          option: [
              AirbridgeTrackingLinkOption.CAMPAIGN: "test_campaign",
              AirbridgeTrackingLinkOption.FALLBACK_IOS: "https://example.com/",
              AirbridgeTrackingLinkOption.FALLBACK_ANDROID: "https://example.com/",
              AirbridgeTrackingLinkOption.FALLBACK_DESKTOP: "https://example.com/"
          ],
          onSuccess: { trackingLink in
              // Handling created tracking-link
          },
          onFailure: { error in
              // Handling error
          }
      )
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      [Airbridge createTrackingLinkWithChannel:@"test_channel" option:@{
          AirbridgeTrackingLinkOption.CAMPAIGN: @"test_campaign",
          AirbridgeTrackingLinkOption.FALLBACK_IOS: @"https://example.com/",
          AirbridgeTrackingLinkOption.FALLBACK_ANDROID: @"https://example.com/",
          AirbridgeTrackingLinkOption.FALLBACK_DESKTOP: @"https://example.com/"
      } onSuccess:^(AirbridgeTrackingLink* trackingLink) {
          // Handling created tracking-link
      } onFailure:^(NSError* error) {
          // Handling error
      }];
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

### 인앱에서 트래킹 링크 활용하기

링크를 여는 방식에 따라 인앱에서 해당 앱의 트래킹 링크를 정상적으로 활용하기 어려울 수 있습니다.

`Airbridge.click` 함수 또는 `Airbridge.impression` 함수를 이용하면 외부 브라우저를 거치지 않고 트래킹 링크를 정상적으로 활용할 수 있습니다.

<AccordionGroup>
  <Accordion title="인앱에서 트래킹 링크를 클릭">
    유저가 인앱에서 트래킹 링크를 클릭하면 `Airbridge.click` 함수를 호출합니다. 해당 함수를 호출하면 트래킹 링크 설정에 따라 스킴 딥링크를 전달하거나 앱마켓, 웹 사이트로 보냅니다.

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      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
      }
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #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
      }
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="인앱에서 트래킹 링크에 노출">
    유저가 트래킹 링크에 노출되면 `Airbridge.impression` 함수를 호출합니다. 해당 함수를 호출하면 노출(Impression) 이벤트를 수집합니다.

    <CodeGroup>
      ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import Airbridge
      ...
      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
      }
      ```

      ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      #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
      }
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

<Danger>
  **주의하세요**

  에어브릿지의 iOS SDK 1.24.0 이상에서 인앱에서 트래킹 링크 활용하기를 설정하면 앱에서 트래킹 링크를 사용할 때마다 딥링크 페이지뷰(Deeplink Pageview)가 [타겟 이벤트](/ko/guides/airbridge-attribution-model#타겟-이벤트)로 집계됩니다. 딥링크 실행(Deeplink Open) 직후에 딥링크 페이지뷰가 빈번하게 발생하면 딥링크 실행 성과에 영향을 줄 수 있습니다.

  딥링크 페이지뷰의 어트리뷰션 윈도우 기본 설정은 3일입니다. 딥링크 페이지뷰의 어트리뷰션 윈도우 변경을 원하는 고객사는 에어브릿지 CSM에게 요청해 주세요. 담당 CSM이 없는 경우 [문의하기](https://app.airbridge.io/supports)를 통해 요청해 주세요.
</Danger>

### 어트리뷰션 결과 활용하기

<Danger>
  **주의하세요**

  에어브릿지 SDK가 어트리뷰션 결과를 수집하는데 시간이 필요합니다. 실시간 처리가 필요한 기능에 어트리뷰션 결과를 활용하는 것을 권장하지 않습니다.
</Danger>

`setOnAttributionReceived` 함수로 설치 이벤트에 대한 어트리뷰션 결과를 받을 수 있습니다.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
      .setOnAttributionReceived({ attribution in
          // when attribution is received
      })
      .build()
  Airbridge.initializeSDK(option: option)
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>
  ...
  AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                 token:@"YOUR_APP_SDK_TOKEN"];
  [optionBuilder setOnAttributionReceived:^(NSDictionary<NSString *,NSString *> * attribution) {
      // when attribution is received
  }];
  AirbridgeOption* option = [optionBuilder build];
  [Airbridge initializeSDKWithOption:option];
  ```
</CodeGroup>

어트리뷰션 결과 존재 여부에 따라 아래와 같이 값이 전달됩니다.

<AccordionGroup>
  <Accordion title="어트리뷰션 결과 존재">
    어트리뷰션 결과가 존재하면 아래 값을 포함한 Dictionary가 콜백으로 전달됩니다. 모든 키는 광고 성과에 기여한 데이터를 제공합니다. 예를 들어 `attributedChannel`에는 광고 성과에 기여한 광고 채널에 대한 정보가 있습니다.

    어트리뷰션 결과는 앱 설치 이벤트가 전송되고 나서 1분 이내에 콜백으로 전달됩니다. 앱이 종료되어 전달되지 않은 이전 어트리뷰션 결과는 다음에 앱을 실행하면 1분 이내에 콜백으로 전달됩니다. 네트워크 환경 등에 따라 최대 5분까지 지연될 수 있습니다.

    | 키                          | 타입     | 설명      |
    | -------------------------- | ------ | ------- |
    | attributedChannel          | String | 채널      |
    | attributedCampaign         | String | 캠페인     |
    | attributedAdGroup          | String | 광고 그룹   |
    | attributedAdCreative       | String | 광고 소재   |
    | attributedContent          | String | 콘텐츠     |
    | attributedTerm             | String | 키워드     |
    | attributedSubPublisher     | String | 하위매체    |
    | attributedSubSubPublisher1 | String | 하하위매체 1 |
    | attributedSubSubPublisher2 | String | 하하위매체 2 |
    | attributedSubSubPublisher3 | String | 하하위매체 3 |
  </Accordion>

  <Accordion title="어트리뷰션 결과 없음 (오가닉)">
    어트리뷰션 결과가 없으면 아래 Dictionary가 콜백으로 전달됩니다.

    ```json lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    {
        "attributedChannel": "unattributed"
    }
    ```
  </Accordion>
</AccordionGroup>

### 푸시 알림으로 딥링크 이벤트 수집하기

푸시 알림을 클릭한 이후 페이로드에 있는 딥링크 정보를 에어브릿지 SDK에 전달해야 딥링크 이벤트를 수집합니다. `Airbridge.trackDeeplink` 함수로 설정해 주세요.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge

  func application(
      _ application: UIApplication,
      didReceiveRemoteNotification userInfo: [AnyHashable : Any],
      fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
  ) {
      if UIApplication.shared.applicationState == .inactive {
          let url = // Deep link from the push notification

          Airbridge.trackDeeplink(url)
      }
  }

  func userNotificationCenter(
      _ center: UNUserNotificationCenter,
      didReceive response: UNNotificationResponse,
      withCompletionHandlercompletionHandler: @escaping () -> Void
  ) {
      if 
          UIApplication.shared.applicationState == .inactive || UIApplication.shared.applicationState == .background,
          response.actionIdentifier == UNNotificationDefaultActionIdentifier
      {
          let url = // Deep link from the push notification

          Airbridge.trackDeeplink(url)
      }
  }
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>

  - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
      if (UIApplication.sharedApplication.applicationState == UIApplicationStateInactive) {
          NSURL* url = // Deep link from the push notification

          [Airbridge trackDeeplinkWithUrl:url];
      }
  }

  - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
      if ((UIApplication.sharedApplication.applicationState == UIApplicationStateInactive || UIApplication.sharedApplication.applicationState == UIApplicationStateBackground)
          && [response.actionIdentifier isEqual:UNNotificationDefaultActionIdentifier])
      {
          NSURL* url = // Deep link from the push notification

          [Airbridge trackDeeplinkWithUrl:url];
      }
  }
  ```
</CodeGroup>

### 에어브릿지 딥링크만 추적하기

에어브릿지 SDK는 에어브릿지 딥링크가 아니더라도 그 어떤 딥링크로 앱이 실행만 되면 해당 딥링크 이벤트를 수집합니다. `setTrackAirbridgeDeeplinkOnlyEnabled`함수를 true로 설정하면 에어브릿지 딥링크로 앱이 실행될 때만 해당 딥링크 이벤트만 수집하도록 하여 불필요한 이벤트 수집을 방지할 수 있습니다.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
      .setTrackAirbridgeDeeplinkOnlyEnabled(true)
      .build()
  Airbridge.initializeSDK(option: option)
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>
  ...
  AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                 token:@"YOUR_APP_SDK_TOKEN"];
  [optionBuilder setTrackAirbridgeDeeplinkOnlyEnabled:YES];
  AirbridgeOption* option = [optionBuilder build];
  [Airbridge initializeSDKWithOption:option];
  ```
</CodeGroup>

### Action Extension으로 이벤트 수집하기

<Info>
  에어브릿지 iOS SDK 4.0.0 이상이 필요합니다.
</Info>

에어브릿지 SDK는 [Action Extension](https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/Action.html)로 이벤트를 수집하는 것을 지원합니다. 다음 방법을 통해 Action Extension에서 [trackEvent](/ko/developers/ios-sdk-v4#인앱-이벤트-전송하기) 함수를 활용하여 이벤트를 수집할 수 있습니다.

1. App Group을 추가합니다.
2. Xcode의 \[YOUR\_PROJECT]>\[Signing & Capabilities]로 이동합니다. + Capability 를 클릭하고 App Groups 를 추가합니다. App Groups에 아래 값을 입력합니다.
   * `group.YOUR_DOMAIN.YOUR_DOMAIN.YOUR_PRODUCT.airbridge`

`group.YOUR_DOMAIN.YOUR_DOMAIN.YOUR_PRODUCT.airbridge` 는 고정된 값이 아닙니다. 원하는 값을 사용할 수 있습니다.

3. App Extension의 `viewDidLoad` 함수에서 SDK를 초기화합니다.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  override func viewDidLoad() {
      super.viewDidLoad()
      let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
          .setAppGroup("group.YOUR_DOMAIN.YOUR_DOMAIN.YOUR_PRODUCT.airbridge")
          .build()
      Airbridge.initializeSDK(option: option)
  }
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>
  ...
  - (void)viewDidLoad {
      [super viewDidLoad];
      AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                     token:@"YOUR_APP_SDK_TOKEN"];
      [optionBuilder setAppGroup:@"group.YOUR_DOMAIN.YOUR_DOMAIN.YOUR_PRODUCT.airbridge"];
      AirbridgeOption* option = [optionBuilder build];
      [Airbridge initializeSDKWithOption:option];
  }
  ```
</CodeGroup>

<Danger>
  **주의하세요**

  `setAppGroup` 설정을 신중하게 결정해야 합니다. 기존 에어브릿지 SDK와 관련된 모든 정보를 삭제해야 `setAppGroup` 설정을 제거하거나 변경할 수 있습니다. 이로 인해 이미 수집된 설치 이벤트가 다시 수집되는 현상 같은 기대하지 않은 결과가 발생할 수 있습니다.
</Danger>

### 구글 디지털 시장법(DMA) 준수

구글 디지털 시장법을 준수하기 위해서는 유저 동의 정보(User Consent)를 에어브릿지에 전달해야 합니다. 구글 디지털 시장법과 적용 대상 등에 대한 자세한 내용은 [에어브릿지 가이드](/ko/guides/supporting-the-updated-google-eu-user-consent-policy)를 참고해 주세요.

<Danger>
  **주의하세요**

  2024년 3월 6일부터 EEA 지역에 있는 기존 유저와 신규 유저에 대한 유저 동의 정보를 최소 1회 수집해야 합니다.
</Danger>

투명성 및 동의 프레임워크(Transparency and Consent Framework) v2.2 프로토콜을 준수하는 사용자 동의 관리 플랫폼(CMP)을 사용하여 유저 동의 정보를 저장하고 있다면, 다음 방법을 통해 에어브릿지 SDK로 유저 동의 정보를 수집할 수 있습니다.

<Accordion title="사용자 동의 관리 플랫폼을 통해 유저 동의 정보 수집">
  <Info>
    **알립니다**

    에어브릿지 iOS SDK 4.4.0 이상이 필요합니다.
  </Info>

  1. SDK 초기화 시, `setCollectTCFDataEnabled` 함수를 true로, `setAutoStartTrackingEnabled` 함수를 false로 설정하세요.

  <CodeGroup>
    ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    let option = AirbridgeOptionBuilder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
        // Make Airbridge SDK explicitly Collect TCFData
        .setCollectTCFDataEnabled(true)
        // Make Airbridge SDK explicitly start tracking
        .setAutoStartTrackingEnabled(false)
        .build()

    Airbridge.initializeSDK(option: option)
    ```

    ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    AirbridgeOptionBuilder *optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME" token:@"YOUR_APP_SDK_TOKEN"];
    // Make Airbridge SDK explicitly Collect TCFData
    optionBuilder = [optionBuilder setCollectTCFDataEnabled:YES];
    // Make Airbridge SDK explicitly start tracking
    optionBuilder = [optionBuilder setAutoStartTrackingEnabled:NO];

    AirbridgeOption *option = [optionBuilder build];
    [Airbridge initializeSDKWithOption:option];
    ```
  </CodeGroup>

  2. 사용자 동의 관리 플랫폼을 사용하여 유저 동의 정보를 저장한 이후에 `startTracking` 함수를 호출하세요.

  <CodeGroup>
    ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    // Explicitly start tracking
    Airbridge.startTracking()
    ```

    ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    // Explicitly start tracking
    [Airbridge startTracking];
    ```
  </CodeGroup>
</Accordion>

그외의 경우, 에어브릿지 SDK로 유저 동의 정보를 수집하려면 다음 방법을 참고하세요.

<Accordion title="Airbridge.setDeviceAlias 함수를 사용하여 유저 동의 정보 수집">
  <Info>
    **알립니다**

    에어브릿지는 유저 동의 정보 저장과 프롬프트 구현 방식 등에 관해 도움을 드릴 수 없습니다. 법률 자문사와 함께 검토해 주세요.
  </Info>

  1. 앱을 실행한 유저의 지역 정보를 확인하세요. 유저가 앱을 실행한 지역이 EEA(`eea=1`)라면 기존에 수집한 유저 동의 정보가 있는지 확인하세요. 유저가 앱을 실행한 지역이 EEA가 아니라면 유저 동의 정보를 수집하지 않아도 됩니다.

  <CodeGroup>
    ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    let option = AirbridgeOptionBuilder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
        // Make Airbridge SDK explicitly start tracking
        .setAutoStartTrackingEnabled(true)
        .build()

    Airbridge.initializeSDK(option: option)
    ```

    ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    AirbridgeOptionBuilder *optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME" token:@"YOUR_APP_SDK_TOKEN"];
    // Make Airbridge SDK explicitly start tracking
    optionBuilder = [optionBuilder setAutoStartTrackingEnabled:YES];

    AirbridgeOption *option = [optionBuilder build];
    [Airbridge initializeSDKWithOption:option];
    ```
  </CodeGroup>

  2. 기존에 수집한 유저 동의 정보가 없다면 프롬프트 등으로 유저 동의 정보를 수집해야 합니다. 수집해야 하는 유저 동의 정보는 `adPersonalization`, `adUserData`입니다.

  에어브릿지 SDK를 초기화한 후, `Airbridge.setDeviceAlias` 함수를 통해 유저의 지역 정보와 수집한 유저 동의 정보를 에어브릿지 SDK에 전달하세요.

  <CodeGroup>
    ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    // Based on actual region
    Airbridge.setDeviceAlias("eea", "0" or "1")

    // Based on actual user consent
    Airbridge.setDeviceAlias("adPersonalization", "0" or "1")
    Airbridge.setDeviceAlias("adUserData", "0" or "1")
    ```

    ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    // Based on actual region
    [Airbridge setDeviceAliasWithKey:"eea" value:"0" or "1"];

    // Based on actual user consent
    [Airbridge setDeviceAliasWithKey:"adPersonalization" value:"0" or "1"];
    [Airbridge setDeviceAliasWithKey:"adUserData" value:"0" or "1"];
    ```
  </CodeGroup>

  수집한 유저 동의 정보를 전달할 때, 반드시 에어브릿지에서 지정한 필드명과 값을 사용해야 합니다. 에어브릿지 SDK에 전달해야하는 유저 동의 정보에 대한 자세한 내용은 아래를 참고하세요.

  | <span style={{ display: 'inline-block', minWidth: '80px' }}>에어브릿지 필드 이름</span> | <span style={{ display: 'inline-block', minWidth: '80px' }}>구글 필드 이름</span> | <span style={{ display: 'inline-block', minWidth: '160px' }}>설명</span>                                       |
  | ------------------------------------------------------------------------------ | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
  | `eea`<br />\<string>                                                           | `eea`                                                                       | 디지털 시장법 준수 지역 여부.<br />- `0`: 디지털 시장법 준수와 관계 없는 지역. EEA 지역에 해당하지 않음.<br />- `1`: 디지털 시장법 준수 지역. EEA 지역에 해당함. |
  | `adPersonalization`<br />\<string>                                             | `ad_personalization`                                                        | 개인 맞춤형 광고 제공을 위한 정보 수집에 대한 동의 여부.<br />- `0`: 유저가 정보 수집에 동의하지 않음.<br />- `1`: 유저가 정보 수집에 동의함.                |
  | `adUserData`<br />\<string>                                                    | `ad_user_data`                                                              | 유저 데이터를 구글에 전송하는 것에 대한 동의 여부.<br />- `0`: 유저가 전송에 동의하지 않음.<br />- `1`: 유저가 전송에 동의함.                          |

  3. 에어브릿지 SDK에 유저 동의 정보를 전달한 이후에 `startTracking` 함수를 호출하세요.

  <CodeGroup>
    ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    // Explicitly start tracking
    Airbridge.startTracking()
    ```

    ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    // Explicitly start tracking
    [Airbridge startTracking];
    ```
  </CodeGroup>
</Accordion>

### 메타 디퍼드 앱 링크 설정하기

<Danger>
  **주의하세요**

  메타 디퍼드 앱 링크를 설정하면 Facebook SDK의 `fetchDeferredAppLink` 함수를 사용하면 안 됩니다.
</Danger>

아래 방법으로 메타 애즈에서 [디퍼드 딥링크](/ko/developers/ios-sdk-v4#디퍼드-딥링크-설정하기)를 제공할 수 있습니다. 에어브릿지 SDK는 메타 디퍼드 앱 링크를 먼저 수집합니다. 메타 디퍼드 앱 링크가 없으면 에어브릿지 디퍼드 딥링크를 수집합니다.

메타 애즈의 SKAdNetwork 캠페인은 메타 디퍼드 앱 링크를 지원하지 않습니다.

1. Facebook SDK를 설치합니다. [메타 애즈 가이드](https://developers.facebook.com/docs/ios/getting-started)를 참고해 주세요.
2. 에어브릿지 SDK의 `setTrackMetaDeferredAppLinkEnabled` 함수를 true로 설정합니다.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
      .setTrackMetaDeferredAppLinkEnabled(true)
      .build()
  Airbridge.initializeSDK(option: option)
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>
  ...
  AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                 token:@"YOUR_APP_SDK_TOKEN"];
  [optionBuilder setTrackMetaDeferredAppLinkEnabled:YES];
  AirbridgeOption* option = [optionBuilder build];
  [Airbridge initializeSDKWithOption:option];
  ```
</CodeGroup>

### 비활성화 상태로 에어브릿지 SDK 초기화하기

<Danger>
  **주의하세요**

  에어브릿지 SDK 초기화 이후 바로 활성화하지 않으면 설치, 오픈, 딥링크 이벤트가 수집되지 않을 수 있습니다.
</Danger>

에어브릿지 SDK를 초기화하면 모든 기능을 활성화합니다. `setSDKEnabled` 함수를 false로 설정하면 모든 기능을 비활성화한 상태로 에어브릿지 SDK를 초기화할 수 있습니다.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
      .setSDKEnabled(false)
      .build()
  Airbridge.initializeSDK(option: option)
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>
  ...
  AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                 token:@"YOUR_APP_SDK_TOKEN"];
  [optionBuilder setSDKEnabled:NO];
  AirbridgeOption* option = [optionBuilder build];
  [Airbridge initializeSDKWithOption:option];
  ```
</CodeGroup>

또는 아래 방식으로 에어브릿지 SDK의 활성화 여부를 확인하고 모든 기능을 활성화하거나 비활성화할 수 있습니다.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  Airbridge.isSDKEnabled
  Airbridge.enableSDK()
  Airbridge.disableSDK()
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>
  ...
  Airbridge.isSDKEnabled;
  [Airbridge enableSDK];
  [Airbridge disableSDK];
  ```
</CodeGroup>

### 앱 삭제 트래킹 설정하기

에어브릿지는 앱 이벤트를 최근 6개월 동안 1번이라도 트래킹한 유저를 대상으로 사일런트 푸시를 매일 KST(한국표준시) 0시\~1시 사이에 보내서 앱 삭제 여부를 확인합니다. 앱 삭제 이벤트는 에어브릿지 리포트와 원본 데이터 추출 등으로 확인할 수 있습니다.

자세한 설정 방법과 설명은 에어브릿지 가이드를 참고해 주세요.

* [앱 삭제 트래킹 설정하기 - iOS SDK (v4)](/ko/developers/uninstall-tracking-ios-sdk-v4)

### 서드파티 연동하기

일부 서드파티 솔루션을 연동하기 위해서는 SDK 설정이 필요합니다. 에어브릿지 SDK로 데이터를 수집하기 전에 서드파티 솔루션에 필요한 설정을 마치는 것을 권장합니다.

각 서드파티 솔루션 연동에 필요한 설정은 아래 가이드를 참고해 주세요.

<Accordion title="에어브릿지와 연동된 서드파티">
  * [앰플리튜드](/ko/guides/amplitude)
  * [구글 애널리틱스 4 (GA4)](/ko/guides/google-analytics-4)
  * [모인게이지](/ko/guides/moengage)
  * [믹스패널](/ko/guides/mixpanel)
  * [브레이즈](/ko/guides/braze)
  * [클레버탭](/ko/guides/clevertap)
  * [레비뉴캣](/ko/guides/revenuecat)
  * [어댑티](/ko/guides/adapty)
  * [앱러빈 맥스](/ko/guides/applovin-max)
  * [게임애널리틱스](/ko/guides/gameanalytics)
  * [앱스토어 커넥트](/ko/guides/app-store-connect)
  * [서치애드닷컴](/ko/guides/search-ads-dot-com)
  * [세그먼트](/ko/guides/segment)
  * [유니티 레벨플레이 (아이언 소스)](/ko/guides/unity-levelplay)
</Accordion>

### SDK 로그 확인하기

에어브릿지 SDK가 제공하는 로그는 Debug, Info, Warning, Error, Fault 레벨로 구성됩니다. Debug 레벨이 가장 덜 치명적인 로그이고, Fault 레벨이 가장 치명적인 로그입니다.

에어브릿지 SDK는 Warning, Error, Fault 레벨 이상의 로그를 기본적으로 제공합니다. `setLogLevel` 함수에 로그 레벨을 입력하면 해당 로그 레벨부터 Fault 레벨까지 로그를 확인할 수 있습니다.

<CodeGroup>
  ```swift Swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  import Airbridge
  ...
  let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN")
      .setLogLevel(.debug)
      .build()
  Airbridge.initializeSDK(option: option)
  ```

  ```objective-c Objective-C lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  #import <Airbridge/Airbridge.h>
  ...
  AirbridgeOptionBuilder* optionBuilder = [[AirbridgeOptionBuilder alloc] initWithName:@"YOUR_APP_NAME"
                                                                                 token:@"YOUR_APP_SDK_TOKEN"];
  [optionBuilder setLogLevel:AirbridgeLogLevelDebug];
  AirbridgeOption* option = [optionBuilder build];
  [Airbridge initializeSDKWithOption:option];
  ```
</CodeGroup>

<Note>
  **에어브릿지 SDK 로그만 확인하기**

  Xcode의 오른쪽 아래에 있는 필터에 `Subsystem: co.ab180.airbridge`를 입력하면 에어브릿지 SDK 로그만 확인할 수 있습니다.
</Note>

<link rel="alternate" hrefLang="en" href="https://help.airbridge.io/en/developers/ios-sdk-v4" />

<link rel="alternate" hrefLang="ko" href="https://help.airbridge.io/ko/developers/ios-sdk-v4" />
