# 연동하기

## 시작하기전에

이 문서는 adbrix iOS SDK를 iOS 앱에 통합하는 방법을 다룹니다.

더 자세히 알아보려면 [리소스 및 샘플](https://adbrix.gitbook.io/developer-guide/common/resource-and-sample)을 참조하세요.

#### SDK 지원 환경

* iOS 12.0 +
* Xcode 16.1 +

## SDK 설치

adbrix iOS SDK는 CocoaPods, Swift Package Manager(SPM), 수동 설치를 지원합니다.

<details>

<summary>CocoaPods</summary>

**1. CocoaPods 설치**

최신 버전의 CocoaPods을 [설치해주세요](https://guides.cocoapods.org/using/getting-started.html#installation)

**2. 의존성 추가**

Xcode 프로젝트 폴더에 `Podfile` 추가 후 Podfile에 adbrix SDK 의존성을 추가해주세요

```
target 'YourAppTarget' do  
  pod 'adbrix2.0'
end

```

**3. 의존성 설치**

터미널에서 다음의 명령어로 SDK를 설치해 주세요

```
pod install
```

</details>

<details>

<summary>Swift Package Manager(SPM)</summary>

**1. Xcode에서 패키지 의존성 추가**

<img src="https://3478783164-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnJIV3KSW5duLCA7m693B%2Fuploads%2Fgit-blob-c4a410085a590bf6e5050a62e1e96724ef776941%2Fadd_package_dependency.jpg?alt=media" alt="" data-size="original">

**2. adbrix SDK GitHub 저장소 입력**

<img src="https://3478783164-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnJIV3KSW5duLCA7m693B%2Fuploads%2Fgit-blob-a14d965cf6382db401d4b92500fc845b47f2552b%2Fadd_package%20(1).jpg?alt=media" alt="" data-size="original">

저장소 명은 <https://github.com/IGAWorksDev/adbrix-ios-sdk> 입니다.

**3. Dependency Rule 입력 및 타겟에 adbrix 추가**

<img src="https://3478783164-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnJIV3KSW5duLCA7m693B%2Fuploads%2Fgit-blob-e4965939bd881bf69510610767aef2e06972bf18%2Fpackage_product%20(1).jpg?alt=media" alt="" data-size="original">

adbrix SDK는 [유의적 버전(Semantic versioning)2.0](https://semver.org/)을 따릅니다.

</details>

<details>

<summary>수동 설치</summary>

**1. 프레임워크 다운로드**

[여기](https://github.com/IGAWorksDev/adbrix-ios-sdk/releases/)에서 최신 프레임워크를 다운로드해 주세요

**2. 프로젝트에 프레임워크 추가**

Xcode의 Targets -> General -> Frameworks, Libraries, and Embedded Content -> + 클릭 -> Add Others... -> Add Files.. 를 통해 다운로드받은 프레임워크를 추가해 주세요

<img src="https://3478783164-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnJIV3KSW5duLCA7m693B%2Fuploads%2Fgit-blob-2755035ace0336abccd82e59e777ba8e3a494c29%2Fadd_framework%20(1).jpg?alt=media" alt="" data-size="original">

</details>

## SDK 초기화

#### AppDelegate 수정

{% tabs %}
{% tab title="Swift" %}
AppDelegate.Swift 파일에 다음과 같이 SDK를 import 합니다.

```swift
import AdbrixSDK
```

AppDelegate 클래스에 sdk초기화 코드를 추가합니다.

```swift
@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        Adbrix.shared().sdkInit(appkey: "APP_KEY", secretKey: "SECRET_KEY")
        
        return true
    }
}
```

{% endtab %}

{% tab title="Objective-C" %}
AppDelegate.m 파일에 다음과 같이 SDK를 import 합니다.

```objective-c
#import <AdbrixSDK/AdbrixSDK.h>
```

AppDelegate 클래스에 sdk초기화 코드를 추가합니다.

```objective-c
@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    [[Adbrix shared] sdkInitWithAppkey:@"APP_KEY" secretKey:@"SECRET_KEY"];

    return YES;
}
```

{% endtab %}
{% endtabs %}

## SDK 설정

### 로그 활성화하기

디버그 로그를 보려면 `ABConfig.LOG_LEVEL`에 `ABLogLevel`을 설정합니다. 설정된 로그 레벨에 따라 로그가 debug console에 표시됩니다. Log의 Subsystem은 (BundleIdentifier).adbrixLoggerV2 입니다.

| ABLogLevel           | 값 | 설명                                         |
| -------------------- | - | ------------------------------------------ |
| `ABLogLevel.error`   | 6 | Error 로그만 표시                               |
| `ABLogLevel.warning` | 5 | Warning, Error 로그 표시                       |
| `ABLogLevel.info`    | 4 | Info, Warning, Error 로그 표시                 |
| `ABLogLevel.debug`   | 3 | Debug, Info, Warning, Error 로그 표시          |
| `ABLogLevel.verbose` | 2 | Verbose, Debug, Info, Warning, Error 로그 표시 |

예시:

{% tabs %}
{% tab title="Swift" %}

```swift
Adbrix.shared().sdkInit(
    appkey: "APP_KEY",
    secretKey: "SECRET_KEY",
    extraConfig: [ABConfig.LOG_LEVEL: ABLogLevel.verbose]
)
```

{% endtab %}

{% tab title="Objective-C" %}

```objective-c
[[Adbrix shared] sdkInitWithAppkey:@"APP_KEY" 
                  secretKey:@"SECRET_KEY"
                  extraConfig:@{ABConfig.LOG_LEVEL: @(ABLogLevelVerbose)}];
```

{% endtab %}
{% endtabs %}

## 딥링크 오픈 분석

앱의 생명주기에 맞춰 다음의 코드를 추가해주세요.

iOS에서는 [딥링크(Custom URL Schemes)](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app)와 [유니버셜 링크(Universal Links)](https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app)를 통해 앱을 열 수 있습니다. Adbrix SDK는 이러한 링크를 통한 앱 오픈을 분석합니다.

### 유니버셜 링크 연동하기(선택사항)

유니버셜 링크를 사용하려면 Xcode에서 `Signing & Capabilities` 탭으로 이동한 뒤 `+ Capability`를 눌러 `Associated Domains`를 추가해주세요.

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

애드브릭스 콘솔의 `성과측정 > 성과측정 설정 > 도메인 설정`에서 커스텀(브랜드, ABX) 도메인으로 대표 도메인 설정을 합니다.

{% hint style="info" %}
트래킹링크의 원본 도메인은 유니버셜 링크로 사용할 수 없습니다. 커스텀 도메인이 없다면 새 도메인을 생성해주세요.
{% endhint %}

#### Application Identifier 등록

애드브릭스 콘솔의 `성과측정 > 성과측정 설정 > 광고 랜딩 설정`에서 Application Identifier를 등록합니다.

#### Associated Domains 등록

`Associated Domains`에는 콘솔에 등록한 대표 도메인을 `applinks:your-domain.com` 형식으로 등록합니다.

{% hint style="info" %}
브랜드 도메인에는 Apple의 [apple-app-site-association](https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app) 파일이 배포되어 있어야 합니다.
{% endhint %}

#### 트래킹링크 예시

```
https://click2.igaworks.com/api/v1/click/mHZ.....
```

#### 설정 예시

```
applinks:click2.igaworks.com
```

### AppDelegate

{% tabs %}
{% tab title="Swift" %}

```swift
//DeepLink
func application(_ app: UIApplication,
                 open url: URL,
                 options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    
    Adbrix.shared().deepLinkOpen(url: url)
    
    return true
}

// Universal Link
func application(_ application: UIApplication,
                 continue userActivity: NSUserActivity,
                 restorationHandler: @escaping ([any UIUserActivityRestoring]?) -> Void) -> Bool {
    
    guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
          let universalLinkUrl = userActivity.webpageURL else {
        return false
    }
    
    Adbrix.shared().deepLinkOpen(url: universalLinkUrl)
    
    return true
}

```

{% endtab %}

{% tab title="Objective-C" %}

```objective-c
// DeepLink
- (BOOL)application:(UIApplication *)app
            openURL:(NSURL *)url
            options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    
    [[Adbrix shared] deepLinkOpenWithUrl:url];
    
    return YES;
}

// Universal Link
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
    
    if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb] && userActivity.webpageURL) {
        [[Adbrix shared] deepLinkOpenWithUrl:userActivity.webpageURL];
        return YES;
    }
    
    return NO;
}
```

{% endtab %}
{% endtabs %}

### SceneDelegate

{% tabs %}
{% tab title="Swift" %}

```swift
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    
    // DeepLink
    if let deepLinkUrl = connectionOptions.urlContexts.first?.url {
        Adbrix.shared().deepLinkOpen(url: deepLinkUrl)
    }
    
    // Universal Link
    if let userActivity = connectionOptions.userActivities.first,
       userActivity.activityType == NSUserActivityTypeBrowsingWeb,
       let universalLinkUrl = userActivity.webpageURL {
        Adbrix.shared().deepLinkOpen(url: universalLinkUrl)
    }
    
    guard let _ = (scene as? UIWindowScene) else { return }
}

// DeepLink
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    if let deepLinkUrl = URLContexts.first?.url {
        Adbrix.shared().deepLinkOpen(url: deepLinkUrl)
    }
}

// Universal Link
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
    guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
          let universalLinkUrl = userActivity.webpageURL else { return }
    
    Adbrix.shared().deepLinkOpen(url: universalLinkUrl)
}

```

{% endtab %}

{% tab title="Objective-C" %}

```objective-c
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    
    // DeepLink
    UIOpenURLContext *firstURLContext = connectionOptions.URLContexts.allObjects.firstObject;
    if (firstURLContext.URL) {
        [[Adbrix shared] deepLinkOpenWithUrl:firstURLContext.URL];
    }
    
    // Universal Link
    NSUserActivity *firstUserActivity = connectionOptions.userActivities.allObjects.firstObject;
    if ([firstUserActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb] && firstUserActivity.webpageURL) {
        [[Adbrix shared] deepLinkOpenWithUrl:firstUserActivity.webpageURL];
    }
}

// DeepLink
- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts {
    UIOpenURLContext *firstURLContext = URLContexts.allObjects.firstObject;
    if (firstURLContext.URL) {
        [[Adbrix shared] deepLinkOpenWithUrl:firstURLContext.URL];
    }
}

// Universal Link
- (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity {
    if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb] && userActivity.webpageURL) {
        [[Adbrix shared] deepLinkOpenWithUrl:userActivity.webpageURL];
    }
}

```

{% endtab %}
{% endtabs %}

### SwiftUI

```swift
import SwiftUI
import AdbrixSDK

@main
struct SwiftUIApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onOpenURL { url in
                    Adbrix.shared().deepLinkOpen(url: url)
                }
                .onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { userActivity in
                    if let universalLinkUrl = userActivity.webpageURL {
                        Adbrix.shared().deepLinkOpen(url: universalLinkUrl)
                    }
                }
        }
    }
}
```

## 지연된 딥링크(Deferred Deep Link) 핸들링하기

지연된 딥링크는 앱이 설치되지 않은 유저가 링크를 클릭 후 앱을 설치했을때 자동으로 딥링크를 실행합니다. 직접 지연된 딥링크를 핸들링 하려면 다음 메소드를 호출하여 자동 딥링크 실행을 막고 직접 동작 시킬 수 있습니다.

### Delegate 설정

AdbrixDeferredDeepLinkDelegate 프로토콜을 채택한 클래스를 Adbrix 인스턴스에 전달후 디퍼드 딥링크가 호출되는 메소드를 구현합니다.

{% tabs %}
{% tab title="Swift" %}

```swift
class AppDelegate: UIResponder, UIApplicationDelegate, AdbrixDeferredDeepLinkDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        ...
        Adbrix.shared().setDeferredDeepLinkDelegate(self)
        return true
    }

    func didReceive(deferredDeepLink: AdbrixDeepLink) {
        if let deepLink = deferredDeepLink.deepLink,
           let url = URL(string: deepLink) {
            handleDeepLink(url)
        }
    }
}
```

{% endtab %}

{% tab title="Objective-C" %}

```objective-c
@interface AppDelegate () <AdbrixDeferredDeepLinkDelegate>

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    ...
    [[Adbrix shared] setDeferredDeepLinkDelegate:self];
    return YES;
}

- (void)didReceiveDeferredDeepLink:(AdbrixDeepLink *)deferredDeepLink {
    if (deferredDeepLink.deepLink) {
        [self handleDeepLink:deferredDeepLink.deepLink];
    }
}

@end
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
위 Delegate 설정을 하지 않으면 서버로부터 전달받은 지연된 딥링크를 SDK에서 자동으로 `UIApplication.shared.open(deepLinkUrl)` 메소드를 사용하여 호출합니다.
{% endhint %}

## App Tracking Transparency (ATT) 지원

idfa 수집 가능 시점부터 SDK 이벤트를 수집하고 싶다면 SDK 초기화 코드에 다음과 같이 설정 코드를 추가해주세요

### ATT 연동

{% tabs %}
{% tab title="Swift" %}

```
ATTrackingManager.requestTrackingAuthorization { status in
    switch status {
    case .notDetermined:
        Adbrix.shared().attAuthorized(false)
    case .restricted:
        Adbrix.shared().attAuthorized(false)
    case .denied:
        Adbrix.shared().attAuthorized(false)
    case .authorized:
        Adbrix.shared().attAuthorized(true)
    @unknown default:
        Adbrix.shared().attAuthorized(false)
    }
}
```

{% endtab %}

{% tab title="Objective-C" %}

```
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
    switch (status) {
        case ATTrackingManagerAuthorizationStatusAuthorized:
            [[Adbrix shared] attAuthorized:YES];
            break;
        case ATTrackingManagerAuthorizationStatusDenied:
            [[Adbrix shared] attAuthorized:NO];
            break;
        case ATTrackingManagerAuthorizationStatusRestricted:
            [[Adbrix shared] attAuthorized:NO];
            break;
        case ATTrackingManagerAuthorizationStatusNotDetermined:
            [[Adbrix shared] attAuthorized:NO];
            break;
        default:
            [[Adbrix shared] attAuthorized:NO];
            break;
    }
}];
```

{% endtab %}
{% endtabs %}

### 초기화 코드

SDK 초기화 시 `extraConfig` 매개변수에 `ABConfig.TRACKING_TIMEOUT` 설정을 추가하면, 지정된 시간(ABTimeOut)동안 SDK 이벤트를 지연시켜 idfa에 대한 정보를 첫 이벤트 부터 담습니다.

#### ABTimeOut 설정

`ABTimeOut`은 ATT 팝업 응답을 기다리는 최대 시간을 설정하는 열거형입니다. SDK는 이 시간 동안 ATT 팝업에 대한 사용자 응답을 기다린 후 이벤트 수집을 시작합니다.

다음과 같은 옵션이 제공됩니다:

| 옵션               | 설명         |
| ---------------- | ---------- |
| `ABTimeOut._60`  | 60초 동안 대기  |
| `ABTimeOut._120` | 120초 동안 대기 |
| `ABTimeOut._180` | 180초 동안 대기 |

{% hint style="info" %}
사용자가 설정된 시간 내에 ATT 팝업에 응답하지 않더라도, 다음 조건에서는 즉시 이벤트 수집이 시작됩니다:

* ATT 팝업에 대한 사용자 응답(허용/거부)이 있는 경우
* 앱이 백그라운드로 전환된 경우
* 대기 시간이 지난 후
  {% endhint %}

이 설정을 통해 IDFA 수집 가능 여부가 확인된 시점부터 정확한 사용자 데이터를 수집할 수 있습니다.

{% hint style="warning" %}
반드시 ATT 연동 코드를 선행해주세요
{% endhint %}

{% tabs %}
{% tab title="Swift" %}

```swift
    Adbrix.shared().sdkInit(
        appkey: "APP_KEY",
        secretKey: "SECRET_KEY",
        extraConfig: [
            ABConfig.TRACKING_TIMEOUT: ABTimeOut._60
        ]
    )
```

{% endtab %}

{% tab title="Objective-C" %}

```objective-c
    [[Adbrix shared] sdkInitWithAppkey:@"APP_KEY"
                             secretKey:@"SECRET_KEY"
                           extraConfig:@{
        ABConfig.TRACKING_TIMEOUT: @(ABTimeOut_60)
    }];

```

{% endtab %}
{% endtabs %}

## SKAdNetwork(SKAN) 설정

SKAdNetwork 캠페인을 운영하는 경우 다음과 같이 info.plist를 설정해주세요(Adbrix2.0 SDK v3.1.0 이상)

* key값은 `Advertising attribution report endpoint URL (NSAdvertisingAttributionReportEndpoint)` 입니다.
* value값은 다음과 같습니다. `https://dfinery-skadnetwork.com/`

## 완료

SDK 설치 및 초기화가 완료되었습니다.
