# SDK 삽입

## 1. 필수 설정

### SDK 설치

#### Cocoapod 환경에서 SDK 다운로드 방법

XCode 프로젝트 파일중 Podfile 파일에 다음과 같이 SDK를 추가합니다

```
pod 'RW'
```

기존에 SDK를 한번 설치한 경우에는 설치할SDK 버전을 표시해야 하는 경우도 있습니다. 아래와 같이 설치할 SDK버전을 명시적으로 표시하면 됩니다.

```
pod 'RW', '~> 1.1.62'
```

Podfile 에 해당라인을 추가한 후 Terminal 프로그램을 실행하여 다음의 명령을 수행합니다

```
pod install
```

SDK 버전 업데이트의 경우 다음의 명령을 수행합니다.

```
pod update
```

정상적으로 설치가 되면 아래와 같은 폴더 구조를 확인할 수 있습니다.

<div align="left"><img src="https://423922975-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M_ZKcnBFmefw9Yfed6b%2F-M_ZMaBlgtZWTxIWvBYf%2F-M_ZUISF00wuoRK6S3Oc%2FRW_frameworks.png?alt=media&#x26;token=9a369779-273b-4870-878c-9f8310852cbb" alt=""></div>

#### Swift Package Manager를 통한 SDK 다운로드 방법

Xcode File 메뉴에서 Add Packages... 를 클릭합니다.

<figure><img src="https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2FdRJpMlVdauZKiJb6lMRO%2Fimage.png?alt=media&#x26;token=663596e4-52ef-437a-b209-a761056de035" alt=""><figcaption></figcaption></figure>

RW-iOS-SPM 또는 <https://github.com/WisetrackerTechteam/RW-iOS-SPM> 주소로 검색합니다.

최신 버전의 패키지로 선택 후, Add Package 버튼을 클릭합니다.

<figure><img src="https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2FGyQ3YbxDlWtBsiWCUR50%2Fimage.png?alt=media&#x26;token=c1f6f6be-7280-4418-bece-55052ae6d016" alt=""><figcaption></figcaption></figure>

완료되면 설치된 패키지를 확인할 수 있습니다.

<div align="left"><figure><img src="https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2FtHRe66wHCV4oBdlBm3IA%2Fimage.png?alt=media&#x26;token=b35eaa69-5ee5-4e37-a49d-0bc1144b355e" alt=""><figcaption></figcaption></figure></div>

TARGETS → Build Phases → Copy Bundle Resources 에 `dop-native-sdk-inf.js` 파일을 드래그 앤 드랍하여 복사합니다.

<figure><img src="https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2FFMlFZlKWaXp587WdlVxY%2Fimage.png?alt=media&#x26;token=a79ed451-0143-48b7-b413-67bd7f9e8bd4" alt=""><figcaption></figcaption></figure>

<figure><img src="https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2FvB1yB7NzUIpOANPbIt0O%2Fimage.png?alt=media&#x26;token=4be21f00-e0ef-4372-8314-aed368ab7099" alt=""><figcaption></figcaption></figure>

### SDK 설치 - Cocoapod, Swift Package Manger를 사용하지 않을 경우

SDK 파일을  <https://github.com/WisetrackerTechteam/RW-iOS-SDK> 에서 다운로드 합니다.

다운된 파일을 압축 해제하면 다음과 같은 파일이 확인 가능하고 이중 아래에 선택된 3개의 파일을 분석 대상 앱 프로젝트에 추가합니다.

![](https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2Fpk3AbexS18KRNF1PTHG8%2Fimage.png?alt=media\&token=7272a544-3333-48cd-8244-b266971cb094)

프로젝트 선택후 마우스 우클릭, Add Files to 메뉴를 선택합니다.

![](https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2FM0jnJbDePvo8eBND9Hey%2Fimage.png?alt=media\&token=2e33c0b8-e040-4cd8-813b-f901788bed15)

앞에서 다운로드 받고, 압축 해제한 폴더에 들어가서 아래와 같이 추가 대상 파일을 선택하고, 화면 아래쪽 설정은 존재하는 모든 target에 포함되었는지 확인후 추가 하면 됩니다.

![](https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2FvAVAojnTWxd7d8xbAasi%2Fimage.png?alt=media\&token=94d8ffb8-a830-44ec-b2ad-afe495884e72)

BuildSetting 에 아래와 같이 설정을 추가합니다.

![](https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2FrtBc8Y0ZkRNfKHJX4Fz0%2Fimage.png?alt=media\&token=37efd436-a00b-47d2-9279-1ffe3a01c24c)

xcode 가 12.3 이후 버전이고 빌드 과정에서 아래와 유사한 오류가 발생하는 경우가 있으며,

![](https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2FYKj0m0uWm8i3OdigjmKX%2Fimage.png?alt=media\&token=a0bec7b2-e1ec-45f1-8a13-05ca77982e61)

위의 경우에는 아래와 같이 설정을 하고, 빌드를 하면됩니다.

![](https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2Fhh7wsdUjki6IzgLEcsss%2Fimage.png?alt=media\&token=fcb545d5-45d6-4e14-a5f8-63098e237774)

마지막으로, SDK 가 Dependencies 로 사용하는 Couchbase-Lite framework 를 아래의 주소에서 다운로드 합니다. 그리고 위와 동일한 방법으로 대상 프로젝트에 추가하여 줍니다. \
아래의 파일은 다운로드 편의를 위해서 zip 파일로 압축하였습니다. 다운로드 받은 파일을 압축 해제하시고, CouchbaseLite.xcframework 폴더를 프로젝트에 framework 로 추가합니다.\
\
<https://wisetracker-public.s3.ap-northeast-2.amazonaws.com/CouchbaseLite.xcframework.zip>

### dotAuthorizationKey 등록

info.plist 파일을 **Open As Source Code** 방식으로 오픈한 후, 아래 코드를 추가합니다.

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

```markup
<key>dotAuthorizationKey</key>
<dict>
    <key>serviceNumber</key>
    <string>xxxxx</string>
    <key>expireDate</key>
    <string>14</string>
    <key>isDebug</key>
    <string>true</string>
    <key>isInstallRetention</key>
    <string>true</string>
    <key>isFingerPrint</key>
    <string>true</string>
    <key>accessToken</key>
    <string></string>
    <key>useMode</key>
    <string>2</string>
</dict>
```

{% endtab %}
{% endtabs %}

추가한 코드 중 `serviceNumber` 의 value를 올바른 값으로 변경해야 합니다.&#x20;

[<mark style="color:blue;">와이즈트래커 대시보드</mark>](https://analytics.wisetracker.co.kr/)에 로그인하여 설정 > 서비스설정 메뉴에서 '<mark style="color:red;">`서비스번호`</mark>' 항목에 기재된 숫자를 확인 후 복사하여 serviceNumber 값을 변경 해 주세요.

<figure><img src="https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2FtaVvhu8LFUF4EFyG9NzA%2Fimage.png?alt=media&#x26;token=f527c29d-88ab-4157-b7a3-e8bf74265064" alt=""><figcaption><p>서비스번호 확인</p></figcaption></figure>

### HTTP 통신 허용

http통신을 허용하기 위해 NSAppTransportSecurity 를 아래와 같이 추가합니다.

이전과 마찬가지로 info.plist 파일을 **Open As Source Code** 방식으로 오픈한 후, 아래 코드를 추가합니다.

```markup
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
```

### 초기화

* 초기화 방법은 SceneDelegate 가 설정된 경우와 설정되지 않은 경우에 따라 달라집니다.
* SceneDelegate를 사용하지 않으면 AppDelegate에서 초기화작업을 하고, 그렇지 않고 SceneDelegate를 사용하면 SceneDelegate에서 이 작업을 해야 합니다.

#### 1. iOS13 미만 (`SceneDelegate` 없음)

AppDelegate의 `didFinishLaunchingWithOptions` 함수에 SDK를 Initialization하기 위한 코드를 다음과 같이 적용합니다. SDK가 정상적으로 초기화 되었을 때 아래와 같은 기본 분석이 가능합니다.

* 앱 실행 및 방문수, 일/주/월순수방문수 등 방문과 관련된 지표
* 통신사, 단말기, 국가 등 방문자의 단말기 환경으로 부터 추출될 수 있는 지표

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

```swift
import DOT
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
  // S: Wisetracker SDK init
  DOT.initialization(launchOptions, application: application)
  #if DEBUG
    DOT.checkDebugMode(true)
  #else
    DOT.checkDebugMode(false)
  #endif
  // E: Wisetracker SDK init
}
```

{% endtab %}

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

```objectivec
#import <DOT/DOT.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  // S: Wisetracker SDK init
  [DOT initialization:launchOptions application:application];
  #ifdef DEBUG
    [DOT checkDebugMode:true]
  #else
    [DOT checkDebugMode:false]
  #endif
  // E: Wisetracker SDK init
}
```

{% endtab %}
{% endtabs %}

DOT가 사용되는 곳에서는 `import DOT`을 통해 import가 필요합니다. 이하 적용 예시에서는 import하는 부분이 생략되어 있습니다.

#### 2. iOS13 이상 (`SceneDelegate` 사용)

#### 👉 iOS13 이상이어도 SceneDelegate를 사용하지 않을 수도 있어요, 이   때에는 위의 SceneDelegate를 사용하지 않는 경우를 참조하세요.

`SceneDelegate`의 `sceneDidBecomeActive`함수에 SDK를 Initialization하기 위한 코드를 다음과 같이 적용합니다. SDK가 정상적으로 초기화 되었을 때 아래와 같은 기본 분석이 가능합니다.

* 앱 실행 및 방문수, 일/주/월순수방문수 등 방문과 관련된 지표
* 통신사, 단말기, 국가 등 방문자의 단말기 환경으로 부터 추출될 수 있는 지표

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

```swift
import DOT

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
...
  func sceneDidBecomeActive(_ scene: UIScene) {
    // S: Wisetracker SDK init
    DOT.initialization(nil, application: UIApplication.shared)
    #if DEBUG
      DOT.checkDebugMode(true)
    #else
      DOT.checkDebugMode(false)
    #endif
    // E: Wisetracker SDK init
  }
...
}
```

{% endtab %}

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

```objectivec
#import <DOT/DOT.h>

@implementation SceneDelegate
...
- (void)sceneDidBecomeActive:(UIScene *)scene {
  // S: Wisetracker SDK init
  [DOT initialization:nil application:[UIApplication sharedApplication]];
  #ifdef DEBUG
    [DOT checkDebugMode:true]
  #else
    [DOT checkDebugMode:false]
  #endif
  // E: Wisetracker SDK init
}
...
@end
```

{% endtab %}
{% endtabs %}

### 어트리뷰션 데이터 접근 <a href="#accessing_attribution_data_ios" id="accessing_attribution_data_ios"></a>

<mark style="color:red;">`[DOT getAttributedInfo]`</mark> 호출을 통해 와이즈트래커 대시보드에서 생성한 어트리뷰션링크를 통해 앱을 설치한 유저(non-organic)의 attribute 정보를 확인할 수 있습니다.

✅ **필수 체크 사항**

{% stepper %}
{% step %}
iOS SDK 최신버전이 적용되어야 합니다
{% endstep %}

{% step %}
SDK 초기화 함수 `DOT.initialization`호출한 이후 사용해야 합니다.
{% endstep %}
{% endstepper %}

{% tabs %}
{% tab title="Objective-C 예제 코드" %}

```objectivec
#import <DOT/DOT.h>

@implementation SceneDelegate
...
- (void)sceneDidBecomeActive:(UIScene *)scene {
  // S: Wisetracker SDK init
  [DOT initialization:nil application:[UIApplication sharedApplication]];
  #ifdef DEBUG
    [DOT checkDebugMode:true]
  #else
    [DOT checkDebugMode:false]
  #endif
  // E: Wisetracker SDK init
  
  [DOT getAttributedInfo:^(NSDictionary *result) {
    // info를 사용하여 작업 수행
    NSLog(@"current attribution data on AppDelegate : %@ ", result);
  }];
}
...
@end
```

{% endtab %}
{% endtabs %}

<mark style="color:blue;">**`result`**</mark> 파라미터의 형태는 아래의 예시를 참고 해주세요.

(result 파라미터 데이터가 비어있다면 Organic 으로 식별된 결과입니다.)

**① 앱설치(예시)**

```
{
  install_media="P1540365166967",      >> 광고채널    
  install_mediaNm="WISE_TEST1",        >> 광고채널명 
  install_campaign="C1710215861051",   >> 광고캠페인  
  install_campaignNm="WISETRACKER",    >> 광고캠페인명
  install_medium="",                   >> 광고타입
  install_keyword=""                   >> 광고키워드   
}
```

**② 앱실행(예시)**

```
{
  open_media="P1540365166967",
  open_mediaNm="WISE_TEST1",
  open_campaign="C1710215861051",
  open_campaignNm="WISETRACKER",
  open_medium="",
  open_keyword=""
}
```

### Hybrid App을 위한 설정

Hybrid 앱의 경우 앱 내에서 WebView 를 사용하여 웹 컨텐츠를 서비스 하기도 합니다. 이와 같이 Webview 에 의해서 보여지는 웹 컨텐츠의 경우에는 위에서 설명된 Native 화면과는 다른 방식으로 동작하기 때문에, 별도의 분석 코드 적용이 필요합니다. 분석 대상 앱이 만약 Hybrid 앱인 경우에는 아래의 코드를 참고하여 웹 컨텐츠도 분석할 수 있도록 적용을 해야합니다.

앱내에서 사용할 WKWebView의 Delegate 함수에 아래와 같이 분석코드를 적용합니다.

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

```swift
extension WebViewController: WKUIDelegate, WKNavigationDelegate {
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
    DOT.injectSdk(toHtmlDocument: webView, withStartPage: true );
}
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
    DOT.injectSdk(toHtmlDocument: webView,  withStartPage: false);
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    DOT.injectJavascript(withDomSearch: webView, isOnPageFinished: true)
}

  func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
       ...
      if let url = navigationAction.request.url{
         let absoluteString = url.absoluteString
          if (absoluteString.hasPrefix("jscall-dot")) {
             let request: URLRequest? = navigationAction.request
             DOT.setWkWebView(webView, reqeust: request)            
              decisionHandler(.cancel)
             return;
              }          
               ...
         }     
           ...
}
```

{% endtab %}

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

```objectivec
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
     [DOT injectSdkToHtmlDocument:webView withStartPage:true];
  }

- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation {
     [DOT injectSdkToHtmlDocument:webView withStartPage:false];
   }
 
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation {
    NSLog(@"2. didFinishNavigation");
      [DOT injectJavascriptWithDomSearch:webView isOnPageFinished:true];
    }

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
   if([@"jscall-dot" isEqualToString:navigationAction.request.URL.scheme]) {
      NSURLRequest *request = navigationAction.request;
      decisionHandler(WKNavigationActionPolicyCancel);
       [DOT setWkWebView:webView reqeust:request];
       return;

   }
}
```

{% endtab %}
{% endtabs %}

모바일앱내 웹뷰와 PC 혹은 모바일웹뷰로 동시에 사용하는 화면인 경우 아래와 같은 웹킷뷰를 포함한 viewController의 viewWillApeear에 아래와 같이 적용해주세요.

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

```swift
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    webView.evaluateJavaScript("navigator.userAgent") { (userAgent, error) in
         if let ua = userAgent {
            self.webView.customUserAgent = ua as! String + " RW2SDK"
         }
     }
}
```

{% endtab %}

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

```objectivec
-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    
    [[self webview] evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id _Nullable userAgent, NSError * _Nullable error) {
        NSString* addSuffix = [NSString stringWithFormat:@"%@ RW2SDK", userAgent];
        if( @available(iOS 9.0,*)){
            [self webview].customUserAgent = addSuffix;
        }
        else{
            NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:userAgent, @"UserAgent", nil];
            [[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];
        }
    }];
}
```

{% endtab %}
{% endtabs %}

### 이벤트 설정

:white\_check\_mark:화면전환 또는 이벤트 분석을 위한 적용 방법은 플러그인 설정 및 초기화 이후에 아래 링크를 클릭하거나,             좌측 IN-APP EVENT 메뉴를 통해 가이드를 확인하실 수 있습니다.

:point\_right:[<mark style="color:blue;">페이지 분석 가이드로 이동하기</mark> ](https://document.wisetracker.co.kr/v2-developer/in-app-event/configuration/page)

:point\_right:[<mark style="color:blue;">인앱 이벤트 설정으로 이동하기</mark>](https://document.wisetracker.co.kr/v2-developer/in-app-event/configuration)

## 2. 고급 설정

고급 설정이란 반드시 적용할 필요는 없지만 와이즈트래커의 확장된 분석기능을 활용하기 위해 추가해야 하는 설정을 말합니다. 필요에 따라 선택적으로 설정을 추가해주시기 바랍니다.

### Universal Link 설정

유니버셜 링크 설정 가이드는 별도의 문서에 정리되어 있습니다.

{% content-ref url="universal-link" %}
[universal-link](https://document.wisetracker.co.kr/v2-developer/sdk/ios/universal-link)
{% endcontent-ref %}

#### Universal Link 분석

continueUserActivity 부분에 아래와 같이 적용이 되면 유니버셜 링크를 통한 광고분석이 가능합니다.

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

```swift
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
    // 아래의 코드를 적용해주세요
    if let uniLink = userActivity.webpageURL?.absoluteString {
        DOT.setDeepLink(uniLink)
        let landingUri :String = DOT.parseAttributionLink(toGetDeeplinkUrl: uniLink)
         // 리턴받은 landingUri값(DeepLink Sheme)으로 화면 진입 로직 구현(기존 open url에서 사용하던 화면 이동 로직과 동일하게 구현하면 됨)
    }
    //
    return false;
 }
```

{% endtab %}
{% endtabs %}

### 딥링크 설정 <a href="#deeplink_ios_setting" id="deeplink_ios_setting"></a>

* 딥링크가 설정된 url 을 통해서 오픈된 이벤트를 분석합니다. 분석을 하기 위해서는 앱에 `custom url scheme` 설정해야 합니다.

![](https://423922975-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M_ZKcnBFmefw9Yfed6b%2F-M__3tAJibWpLmGOvz7o%2F-M__4aa2RrrWa34V_aoK%2FdeepLink_setting.png?alt=media\&token=d9c207fc-eb1d-47f3-99f2-7f6261801cd0)

:heavy\_check\_mark:`와이즈트래커 대시보드에서 생성한 어트리뷰션링크를 통해 테스트 및 광고집행`을 진행하며, 딥링크 클릭 시 와이즈트래커 서버가 앱의 설치 여부를 판단하여 동작합니다. 다음과 같은 형태의 ***"<https://xxxx.page.link>"*** 링크를 클릭하게 되면 해당 URL이 가르키는 웹으로 이동함으로써 `와이즈트래커가 수집하여야 하는 광고파라미터값이 유실`될 수 있어, <mark style="color:red;">**앱으로 바로 이동 가능한 다음과 같은 형태의 Unique 한 커스텀스키마가 필요**</mark>합니다.&#x20;

이미 만들어진 유니버셜링크가 존재 한다면 와이즈트래커에서 사용할 딥링크 진입 스키마 설정을 `'추가'` 해 주세요. (딥링크스키마 설정 추가시 다른 링크에 어떠한 영향도 주지 않습니다.)

위와 같이 설정을 마치시게 되시면 예를들어 다음과 같 형태의 커스텀 스키마가 생성됩니다.&#x20;

### <mark style="background-color:orange;">wisetracker://</mark><mark style="background-color:green;">wisetracker.co.kr</mark>

여기서 <mark style="color:orange;">**wisetracker://**</mark> 부분이`Scheme(혹은 프로토콜)` 입니다. 개발자가 앱에 이 Scheme를 쓸 것이라고 결정하는 것이며, 해당 Scheme만 설정을 하셔도 됩니다.

이어서 <mark style="color:green;">**wisetracker.co.kr**</mark> 부분은 특정 페이지에 도달하도록 만들기 위한 `host(혹은 path or 도메인)` 입니다.

그리고 **wisetracker://wisetracker.co.kr?**<mark style="color:purple;">**product=1**</mark> 이러한 형태로 만드는 경우는 `특정 페이지로 이동하기 위한 parameter 값을 지정`하는 것이며 해당 부분은 와이즈트래커의 SDK가 아닌 **고객사측에서 직접 설정**해주셔야 하는 값이며, 특정 페이지로 이동할 필요가 없다면 parameter 값은 꼭 설정하지 않아도 됩니다.

#### 딥링크 분석

* 앱이 설치된 이후 DeepLink를 통해서 앱이 실행되는 경로 분석이 필요한 경우 아래와 같이 `setDeepLink` 함수를 사용하면 분석이 가능합니다.

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

```swift
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
	DOT.setDeepLink(url.absoluteString)
	return true
}
```

{% endtab %}

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

```objectivec
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
	[DOT setDeepLink:[url absoluteString]];
	return YES;
}
```

{% endtab %}
{% endtabs %}

### 딥링크 예외 처리 <a href="#deeplink_exception_ios" id="deeplink_exception_ios"></a>

와이즈트래커 SDK를 적용하고, 광고 분석을 하고자 하는 경우, 와이즈트래커 시스템에서 발급된 광고 분석 링크에 의해서 앱을 실행하는 딥링크 URL에 다음과 같이 광고 분석 목적의 파라미터가 추가될 수 있습니다.&#x20;

특히 웹앱의 경우 url 이라는 파라미터를 사용하여 웹뷰에 로딩되어질 웹페이지 url을 전달하는 경우가 많은데, 이와 관련하여 아래의 케이스에도 문제가 없는지 반드시 확인하시기 바랍니다.

```
// 기존의 deeplink 에 광고 분석 파라미터가 추가된 예시를 보여주고 있습니다.
YOUR_SCHEMA://YOUR_HOST?url={YOUR_WEB_PAGE_URL}&trackId=M00200881641977334670
&w_start=h&_wtno=102&_wts=P1641977288745
... 중간 생략 ...
&w_end=h
```

{% file src="<https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2FzFPCmoKmgcwPYiuiKTaQ%2FSDK%E1%84%83%E1%85%A6%E1%84%8B%E1%85%B5%E1%84%90%E1%85%A5%E1%84%80%E1%85%A5%E1%86%B7%E1%84%8C%E1%85%B3%E1%86%BC%20%E1%84%80%E1%85%A1%E1%84%8B%E1%85%B5%E1%84%83%E1%85%B3%E1%84%87%E1%85%AE%E1%86%A8.pdf?alt=media&token=dd0588bb-eca8-44c7-b07a-1625f5758d95>" %}
딥링크 설정 후 테스트시 가이드북을 참고해 주세요.
{% endfile %}

### Deffered Deep Link (지연된 딥링크) 적용 <a href="#facebook_ad_aos" id="facebook_ad_aos"></a>

{% hint style="info" %}

1. 지연된 딥링크 기능은 `Growth` 레벨 이상의 사용자에게 제공됩니다.
2. 지연된 딥링크 기능 제공 SDK 버전\
   \- Android SDK: Base Modeul - 1.0.81 이상 / New Dot Module - 1.0.51 이상\
   \- iOS SDK: RW 1.1.52 이상
   {% endhint %}

기존의 \[DOT initialization] SDK 초기화 함수 대신 \
아래의 \[DOT initializationForDeferredCallback] 함수를 사용하여,  \
수신된 지연된 딥링크의 처리를 위한 코드를 작성합니다.&#x20;

```java

// your code...

[DOT initializationForDeferredCallback:launchOptions application:application callback:^{
    // deferred deeplink  정보는 [DOT getDeferredUrl]로 사용이 가능하며,
    // 앱에서는 해당 변수를 다음과 같이 사용할  수 있음. 
    // 1. callback 이 호출되는 시점에 즉시 __deferredUrl 화면으로 이동 처리. __deferredUrl 값이 nil 이면 메인 화면으로 이동 처리. 
    // 2. __deferredUrl 변수값을 어딘가에 저장하고, 회원가입 이후, 로그인이 완료된 이후등과 같이 필요한 시점에 저장된 값을 꺼내서 이동 처리. 
    // 3. 사용 가능한 Deferred deeplink 정보가 없는 경우에는, __deferredUrl 값이 널(NULL) 이 될 수 있음을 고려하여 사용. 
    NSString* __deferredUrl = [DOT getDeferredUrl];
    NSLog(@"Deferred callback executed %@", __deferredUrl);
}];

// your code...
```

위와 같이 지연된 딥링크에 대한 대응 코드가 적용된 이후에 와이즈트래커 대쉬보드에서 아래와 같이 어트리뷰션 링크를 생성하였다고 가정해보겠습니다.&#x20;

<figure><img src="https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2FygXyc0mZbnmn5suEoZir%2Fimage.png?alt=media&#x26;token=d531672c-9ee1-4049-92ac-ba17f0902c52" alt=""><figcaption></figcaption></figure>

지연된 딥링크(디퍼드 딥링크)가 사용된 어트리뷰션 링크이기 때문에 **만약 앱이 설치되어 있지 않았던 경우라면**, 먼저 앱 설치를 위해 마켓(구글스토어, 앱스토어)으로 이동되고, 앱 설치 이후에 앱을 실행시키게 되면 `NSString* __deferredUrl` 변수에 설정한 `앱 실행` 링크가 들어가 있음을 확인할 수 있습니다. (예: wisetester://mainscreen)

따라서 들어가 있는 (디퍼드) 딥링크 값에 따라 어떻게 처리할지 이후 액션에 대해 대응되는 코드를 개발해 주시면 됩니다.

### Facebook 광고 성과 측정 <a href="#facebook_ad_ios" id="facebook_ad_ios"></a>

Facebook 앱에서 유입되는 설치수를 분석하기 위해서는 Facebook에서 제공하는 SDK가 분석 대상 앱에 설치가 선행되어야 합니다.

#### 비즈니스 인증 <a href="#facebook_business_ios" id="facebook_business_ios"></a>

[<mark style="color:blue;">Facebook Developer</mark>](https://developers.facebook.com/) 사이트의 앱설정-기본설정에서 비즈니스 인증 여부를 확인 해 주세요. 비즈니스 인증이 완료되지 않았을 경우, 리퍼러 정보가 수신되지 않아, facebook 광고 성과에 대한 측정이 어렵습니다.

<figure><img src="https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2FqVxFxZ6noDTKsmJXxTGM%2Fimage.png?alt=media&#x26;token=aa2f6f1e-c2f2-48f8-b38d-597da2baaf32" alt=""><figcaption></figcaption></figure>

#### FBSDK 다운로드 방법

**1) XCode 프로젝트 파일중 Podfile 파일에 다음과 같이 SDK를 추가합니다**

```
pod ‘FBSDKCoreKit’, ‘11.2.1’
```

**2) Podfile 에 dependency 를 추가한 뒤에는 Terminal 프로그램을 실행하여 다음의 명령을 수행합니다**

```
cmd> pod install
```

#### FBSDK 설치 방법

**1) info.plist 파일을 source로 보기 로 오픈합니다**

**2) 이름 속성 아래에 포함된 내용중&#x20;**<mark style="color:red;">**\[APP\_ID]**</mark>**&#x20;,&#x20;**<mark style="color:red;">**\[APP\_NAME]**</mark>**&#x20;,&#x20;**<mark style="color:red;">**\[CLIENT\_TOKEN]**</mark>**&#x20; 부분을 Facebook Developer Site 에서 제공하는 값으로 치환후 info.plist 파일에 저장합니다**

<pre class="language-xml"><code class="lang-xml">&#x3C;key>CFBundleURLTypes&#x3C;/key>
&#x3C;array>
    &#x3C;dict>
        &#x3C;key>CFBundleURLSchemes&#x3C;/key>
        &#x3C;array>
            &#x3C;string>fb<a data-footnote-ref href="#user-content-fn-1">[APP_ID]</a>&#x3C;/string>
        &#x3C;/array>
    &#x3C;/dict>
&#x3C;/array>
&#x3C;key>FacebookAppID&#x3C;/key>
&#x3C;string>[APP_ID]&#x3C;/string>
&#x3C;key>FacebookDisplayName&#x3C;/key>
&#x3C;string>[APP_NAME]&#x3C;/string>
&#x3C;key>FacebookClientToken&#x3C;/key>
&#x3C;string>[CLIENT_TOKEN]&#x3C;/string>
&#x3C;key>FacebookAdvertiserIDCollectionEnabled&#x3C;/key>
&#x3C;true/>
</code></pre>

#### &#x20;FBSDK 로부터 Install Referrer를 수신하고, SDK에 전달하는 방법

{% hint style="warning" %}
이 과정에서 Facebook 지연된 앱 링크가 작동하려면 <mark style="color:red;">Facebook 앱과 앱 모두 ATT(앱 추적 투명성) 권한이 부여</mark>되어야 합니다. FACEBOOK 앱과 귀하의 앱 모두에서 ATT를 활성화한 후 referrer 수신 여부를 체크 해 주세요.
{% endhint %}

사용자가 Facebook에 노출된 광고를 클릭하고 앱을 설치한 경우 설치된 앱에서는 FBSDK를 통해서 AppLinkData를 수신받을 수 있습니다.&#x20;

아래의 코드에서 FBSDK로부터 AppLinkData를 수신 받고, 수신 받은 AppLinkData 를 SDK로 전달하는 방법을 확인할 수 있습니다. 이 함수는 appDelegate의 `didFinishLaunchingWithOptions` 함수에 적용하세요. SDK 초기화 이 후에 `DOT.setFacebookreferrerData()` 호출을 통해 SDK에 리퍼러 url 이 전달될 수 있도록 합니다.

아래는 Facebook 으로부터 Install Referrer를 수신받기 위해, ATT 동의 확인 > 동의 여부에 따라 SDK에 Facebook 리퍼러 데이터를 전달 하는 예제 코드 입니다.&#x20;

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

```swift
import AppTrackingTransparency
import AdSupport
import FBSDKCoreKit
import DOT

func requestTrackingPermission() {
    
    // iOS 14 이상인지 체크
    if #available(iOS 14, *) {
      ATTrackingManager.requestTrackingAuthorization { (AuthorizationStatus) in
        switch AuthorizationStatus {
            // ATT 동의
            case .authorized:
              Settings.setAdvertiserTrackingEnabled(true)
              DispatchQueue.main.async(execute: { [] in
                AppLinkUtility.fetchDeferredAppLink({ url, error in
                  if error != nil {
                    if let anError = error {
                      print("😀 Received error while fetching deferred app link: \(anError)")
                    }
                  }
                  if let unwrappedUrl = url {
                    // Facebook Deferred link 수신 & SDK 전달.
                     print("😀 fetchDeferredAppLink: \(url.absoluteString)")
                      DOT.setFacebookreferrerData(url)
                  }
                })
              })
              // SDK에 IDFA 설정
              DOT.setIDFA(ASIdentifierManager.shared().advertisingIdentifier.uuidString)
            
            //  ATT 거부 및 기타
            @unknown default:
              DOT.denyATT();
        }
      }
    }
    // iOS 14 이하
    else {
      DOT.setATTAuthorizationStatus(3)
      AppLinkUtility.fetchDeferredAppLink({ url, error in
        if error != nil {
          if let anError = error {
            print("😀 Received error while fetching deferred app link: \(anError)")
          }
        }
        if let unwrappedUrl = url {
          // Facebook Deferred link 수신 & SDK 전달.
            DOT.setFacebookreferrerData(unwrappedUrl)
        }
      });
    }
}
```

{% endtab %}

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

```objectivec
#import "AppDelegate.h"
#import <DOT/DOT.h>
#import <AppTrackingTransparency/ATTrackingManager.h>
#import <AdSupport/AdSupport.h>
#import <FBSDKCoreKit/FBSDKCoreKit.h>

- (void)requestTrackingPermission {
  if (@available(iOS 14, *)) {
      [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus authorizationStatus) {
        switch (authorizationStatus) {
          case ATTrackingManagerAuthorizationStatusAuthorized:
                [FBSDKSettings setAdvertiserTrackingEnabled:YES];
                dispatch_async(dispatch_get_main_queue(), ^{
                    NSLog(@"FBSDKAppLinkUtility fetchDeferredAppLink started.");
                    [FBSDKAppLinkUtility fetchDeferredAppLink:^(NSURL *_Nullable url, NSError *_Nullable error) {
                        if (error) {
                            NSLog(@"😀 Received error while fetching deferred app link : %@", error);
                        }
                        if (url) {
                            NSLog(@"😀 fetchDeferredAppLink : %@", [url absoluteString]);
                            [DOT setFacebookreferrerData:url];
                        }
                        else{
                            NSLog(@"😀 fetchDeferredAppLink is nil");
                        }
                        NSLog(@"FBSDKAppLinkUtility fetchDeferredAppLink finished.");
                    }];
                });
              [DOT setIDFA:[[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]];
              break;
          default:
              [DOT denyATT];
              break;
        }
    }];
  } else {
      // 14 이하 IDFA 처리
      [DOT setATTAuthorizationStatus:3];
      
      // 14.0 미만인 경우...
      dispatch_async(dispatch_get_main_queue(), ^{
          [FBSDKAppLinkUtility fetchDeferredAppLink:^(NSURL *_Nullable url, NSError *_Nullable error) {
              if (error) {
                  NSLog(@"😀 Received error while fetching deferred app link: %@", error);
              }
              if (url) {
                      [DOT setFacebookreferrerData:url];
              }
          }];
      });
  }
}

```

{% endtab %}
{% endtabs %}

Facebook SDK와 관련하여 보다 자세한 설치 방법은 아래의 링크에서 확인이 가능합니다.

[FBSDK iOS 적용방법 자세히 보기](https://developers.facebook.com/docs/ios/)

{% hint style="warning" %} <mark style="color:red;">**Facebook 앱 설치형 광고성과 측정을 위한 테스트 시 참고사항**</mark>

iOS의 경우 `Facebook Developer - 앱 광고 지원 도구`를 통해 '**앱 설치형 광고테스트**' 시 iOS 보내기 버튼을 클릭하여도 지연된 딥링크가 아닌 일반적 딥링크로 동작하게 됩니다.&#x20;

iOS테스트이지만 "Android에 보내기" 버튼을 클릭하여 아래와 같은 지연된 딥링크 처리 팝업이 발생되는지 확인 후 테스트를 진행 해 주세요.
{% endhint %}

<figure><img src="https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2F915vArCAOpGVnKe7HOuj%2Fimage.png?alt=media&#x26;token=a6c1a70b-ea72-4767-aa1b-59faa7dda098" alt=""><figcaption><p>앱 설치형 광고 테스트시 확인 팝업 </p></figcaption></figure>

## 4. iOS 14 개인정보방침 변경 관련 가이드 <a href="#ios-ios14-tracking" id="ios-ios14-tracking"></a>

* iOS 14부터 IDFA를 획득하기 위해서는 사용자의 동의를 얻어야 합니다.&#x20;

### 3.1 info.plist파일에 NSUserTrackingUsageDescription 설정 추가

```markup
<key>NSUserTrackingUsageDescription</key>
<string>Your data will be used to deliver personalized ads to you.</string>
```

![](https://423922975-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M_ZKcnBFmefw9Yfed6b%2F-M_cqJw02QhezgBAxmEB%2F-M_cqVkX4qIURMF-BAjx%2FTrackingUsageDescription.png?alt=media\&token=4bd64729-810c-4bcc-8949-9e303df1e776)

### 3.2 App Tracking Transparency 동의 System Alert 노출 & API 호출

<div align="left"><img src="https://423922975-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M_ZKcnBFmefw9Yfed6b%2F-M_cqJw02QhezgBAxmEB%2F-M_cqtvuUq_YNknZJZuW%2FV2_ATT-473x1024.png?alt=media&#x26;token=36483ccf-92a2-40ff-9f3a-a047498887b0" alt=""></div>

* IDFA 획득을 위해 앱 추적 투명성 동의 요청 System Alert(대화 상자)을 띄워야 합니다. 동의 요청 System Alert(대화 상자) 화면에 띄우려면 requestTrackingAuthorizationWithCompletionHandler:를 호출합니다. completionHandler에서 동의 시 SDK API를 호출하도록 위와 같이 구현하시면 됩니다.

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

```swift
import AppTrackingTransparency
import AdSupport
if #available(iOS 14, *) {
	ATTrackingManager.requestTrackingAuthorization { (AuthorizationStatus) in
		if(AuthorizationStatus == .authorized) {
			DOT.setIDFA(ASIdentifierManager.shared().advertisingIdentifier.uuidString)
		}
	}
} else {
	DOT.setATTAuthorizationStatus(3)
}
```

{% endtab %}

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

```objectivec
#import <AppTrackingTransparency/ATTrackingManager.h>
#import <AdSupport/AdSupport.h>
if (@available(iOS 14, *)) {
	[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
		if(status == ATTrackingManagerAuthorizationStatusAuthorized) {
			[DOT setIDFA:[[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]];
		}
	}];
} else {
	[DOT setATTAuthorizationStatus:3];
}
```

{% endtab %}
{% endtabs %}

* 관련 공식 문서 <https://developer.apple.com/app-store/user-privacy-and-data-use/>
* 개발 관련 공식 문서 <https://developer.apple.com/documentation/apptrackingtransparency>

[^1]:
