# SDK 설치 및 API 적용

### SDK설치

{% tabs %}
{% tab title="CocoaPod(APNs)" %}
XCode 프로젝트 파일중 `Podfile` 파일에 다음과 같이 SDK를 추가합니다

```
pod 'RW'
```

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

```
pod 'RW', '~> 1.1.57'
```

#### **`Terminal`**

`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-Mj1tYih-tsuJeRGRXmE%2F-Mj1vd7OB5Fe1DBTTZJS%2FRW_frameworks.png?alt=media&#x26;token=88ca127d-3c84-43b9-ad34-631f9a4a4459" alt=""></div>
{% endtab %}

{% tab title="Swift Package Manager (APNs)" %}
Xcode File 메뉴에서 Add Packages... 를 클릭합니다.

<figure><img src="https://document.wisetracker.co.kr/~gitbook/image?url=https%3A%2F%2F423922975-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-M_ZKcnBFmefw9Yfed6b-3102695190%252Fuploads%252FdRJpMlVdauZKiJb6lMRO%252Fimage.png%3Falt%3Dmedia%26token%3D663596e4-52ef-437a-b209-a761056de035&#x26;width=768&#x26;dpr=4&#x26;quality=100&#x26;sign=13b058db&#x26;sv=1" alt=""><figcaption></figcaption></figure>

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

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

```
현재 가장 최신 버전 1.1.57
```

<figure><img src="https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2FtACM0kGRXsy2l0Ovj7hR%2Fimage.png?alt=media&#x26;token=87ac584e-c55c-434d-b4cf-a28b890bf88c" 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%2FGGUSYSC2nO8J7t4TmSpw%2Fimage.png?alt=media&#x26;token=6be6c27f-8721-4063-8b83-1217dd96a280" alt="" width="123"><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%2FSKgu21Uh4ju6XVatOq13%2Fimage.png?alt=media&#x26;token=818616a9-c2fe-4f11-988b-eaeade740096" 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%2FivMQELsaGnpOVWgIJZMH%2Fimage.png?alt=media&#x26;token=e6bb25cb-d114-4c55-b00d-2eb6802b7898" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Swift Package Manager (FCM)" %}
{% hint style="warning" %}
iOS FCM Push notification의 경우 <mark style="color:red;">**`Wisetracker iOS SDK 1.1.57 버전 이상`**</mark>인 경우 정상동작 합니다.
{% endhint %}

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

#### 1. 와이즈트래커 SDK 적용

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

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

```
현재 가장 최신 버전 1.1.57
```

<figure><img src="https://document.wisetracker.co.kr/~gitbook/image?url=https%3A%2F%2F423922975-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-M_ZKcnBFmefw9Yfed6b-3102695190%252Fuploads%252FGyQ3YbxDlWtBsiWCUR50%252Fimage.png%3Falt%3Dmedia%26token%3Dc1f6f6be-7280-4418-bece-55052ae6d016&#x26;width=768&#x26;dpr=4&#x26;quality=100&#x26;sign=52edc643&#x26;sv=1" alt=""><figcaption></figcaption></figure>

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

#### 2. FCM 사용을 위한 Firebase 적용

```
https://github.com/firebase/firebase-ios-sdk.git
```

(와이즈트래커 SDK와 호환이 가능한 패키지 버전을 직접 선택하여 추가 해주세요)

<figure><img src="https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2Frlna2qXSL5P45O2LFhMa%2Fimage.png?alt=media&#x26;token=c2199514-cabb-45af-94bf-924f87fc002b" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
앱에 Firebase 적용을 위한 자세한 내용은 아래의 Firebase 문서를 참고 해주세요.

* [<mark style="color:blue;">Firebase 설치 유형별 document</mark>](https://firebase.google.com/docs/ios/setup?hl=ko)
* [<mark style="color:blue;">Firebase 설정 및 초기화</mark> ](https://firebase.google.com/docs/ios/setup?hl=ko)
* [<mark style="color:blue;">Firebase 푸시 토큰 확인</mark>](https://firebase.google.com/docs/cloud-messaging/ios/client?hl=ko#swift_1)
* [<mark style="color:blue;">Firebase 푸시알림처리</mark>](https://firebase.google.com/docs/cloud-messaging/ios/receive?hl=ko&_gl=1*c7rlog*_up*MQ..*_ga*MjEwMDkyOTY3NS4xNzI3NjU0ODE2*_ga_CW55HF8NVT*MTcyNzY3MzYzMi4yLjAuMTcyNzY3MzYzMi4wLjAuMA..#handle_alert_notifications)
  {% endhint %}
  {% endtab %}
  {% endtabs %}

### dotAuthorizationKey 등록

#### **`info.plist`**

info.plist 파일을 **Open As Source Code** 방식으로 오픈한 후, 아래 코드를 추가합니다.\
&#x20;추가한 코드 중 4번 라인 `serviceNumber`의 string value를 올바른 값으로 변경해야 합니다.

```markup
...
<!--
  // =======================================================
  // 이 내용은 Wisetracker 기본 SDK가 이미 적용된 경우에는 새로 적용할
  // 필요가 없습니다.  메시징 서비스만 이용하는 경우 참조해주세요.
  // =======================================================
-->
<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>
...
```

\
  대시보드 화면 좌측 메뉴에서 "서비스 설정 > 어플리케이션 설정"화면에서 "서비스 번호"를 복사하여

`info.plist` 파일 4번 라인 `serviceNumber`의 string value로 입력해주세요.

<figure><img src="https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2Fkv14yefpbx4D14NWGNXE%2Fimage.png?alt=media&#x26;token=67f1a405-a299-42d1-9388-741c6a56fcc0" alt=""><figcaption><p>서비스번호 확인</p></figcaption></figure>

### HTTP 통신 허용

#### **`info.plist`**

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

```markup
...
<!--
  // =======================================================
  // 이 내용은 Wisetracker 기본 SDK가 이미 적용된 경우에는 새로 적용할
  // 필요가 없습니다.  메시징 서비스만 이용하는 경우 참조해주세요.
  // =======================================================
-->
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
...
```

### **"Push Notification" Capability 추가**

앱에 푸시기능을 추가합니다.

"Signing & Capabilities" 탭을 선택한 후 화면 왼쪽의 "+ Capability"를 눌러주세요.

![앱설정 화](https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2FhHmaPPqKPrEgLzN8fgOi%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-11-25%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%204.39.15.png?alt=media\&token=0c09e794-d0b2-4d24-96e3-3bc6a0c8a559)

"Capability"화면에서 "Push Notification"기능을 선택합니다.

![Push Notification  기능 추가](https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2FjkbOJ7ilrv7m4NA7A8rl%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-11-25%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%204.39.44.png?alt=media\&token=5d60684b-cef6-420d-ad56-16da341a95b2)

이제 "Push Notification" 기능이 활성화되었습니다.

!["Push Notification" 기능](https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2FK2JfR97nCi2hOPUS03Xk%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-11-25%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%204.40.54.png?alt=media\&token=da31e0fa-7536-4fe6-b7a9-ea59da261f86)

{% hint style="warning" %}
APNs 원격 알림을 받기위해 아래와 같이 **Background Modes** 활성화 체크도 필요합니다

![](https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2FifPaBdgqNYVaIf2jVrLI%2Fimage.png?alt=media\&token=e3c331d6-c7b4-4567-bb8a-cd9a83514c56)
{% endhint %}

### 초기화

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

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

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

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

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

```swift
import DOT

// =======================================================
// AppDelegate에 "UNUserNotificationCenterDelegate" 프로토콜이 선언되어야 합니다.
// =======================================================
@main
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
  ...
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // =======================================================
    // 이 내용은 Wisetracker 기본 SDK가 이미 적용된 경우에는 새로 적용할
    // 필요가 없습니다.  메시징 서비스만 이용하는 경우 참조해주세요.
    // =======================================================
    // Start : Wisetracker SDK 호출
    DOT.initialization(launchOptions, application: application)
    #if DEBUG
      DOT.checkDebugMode(true)
    #else
      DOT.checkDebugMode(false)
    #endif
    // End : Wisetracker SDK init
  }
  ...
}
```

{% endtab %}

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

```objectivec
#import <DOT/DOT.h>
// =======================================================
// AppDelegate에 "UNUserNotificationCenterDelegate" 프로토콜이 선언되어야 합니다.
// =======================================================
@implementation AppDelegate {
...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  // =======================================================
  // 이 내용은 Wisetracker 기본 SDK가 이미 적용된 경우에는 새로 적용할
  // 필요가 없습니다.  메시징 서비스만 이용하는 경우 참조해주세요.
  // =======================================================
  // Start : Wisetracker SDK 호출
  [DOT initialization:launchOptions application:application];
  #ifdef DEBUG
    [DOT checkDebugMode:true]
  #else
    [DOT checkDebugMode:false]
  #endif
  // End : Wisetracker SDK 호출
}
...
@end
```

{% 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) {
    // =======================================================
    // 이 내용은 Wisetracker 기본 SDK가 이미 적용된 경우에는 새로 적용할
    // 필요가 없습니다.  메시징 서비스만 이용하는 경우 참조해주세요.
    // =======================================================
    // Start : Wisetracker SDK 호출
    DOT.initialization(nil, application: UIApplication.shared)
    #if DEBUG
      DOT.checkDebugMode(true)
    #else
      DOT.checkDebugMode(false)
    #endif
    // End : Wisetracker SDK 호출
  }
...
}sw
```

{% endtab %}

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

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

@implementation SceneDelegate
...
- (void)sceneDidBecomeActive:(UIScene *)scene {
  // =======================================================
  // 이 내용은 Wisetracker 기본 SDK가 이미 적용된 경우에는 새로 적용할
  // 필요가 없습니다.  메시징 서비스만 이용하는 경우 참조해주세요.
  // =======================================================
  // Start : Wisetracker SDK 호출
  [DOT initialization:nil application:[UIApplication sharedApplication]];
  #ifdef DEBUG
    [DOT checkDebugMode:true]
  #else
    [DOT checkDebugMode:false]
  #endif
  // End : Wisetracker SDK 호출
}
...
@endo
```

{% endtab %}
{% endtabs %}

## PushMessage API 적용(필수)

### Device Token 등록

Wisetracker SDK 호출 한 코드 아래에 <mark style="color:red;">**푸시 권한을 요청**</mark>하는 코드를 삽입합니다.

:ballot\_box\_with\_check:Objective-C 의 경우 AppDelegate.h 파일에 UserNotifications을 추가한 후&#x20;

```objectivec
// iOS10 부터 UNUserNotification 을 사용하여 서비스 등록 및 처리 방법이 변경되었기 때문에 
// iOS10 버전과 하위버전을 같이 처리할 수 있도록 적용이 필요합니다.
// interface에 UNUserNotificationCenterDelegate 도 추가 해 주세요.
#import <RCTAppDelegate.h>
#import <UIKit/UIKit.h>
#import <UserNotifications/UserNotifications.h>

@interface AppDelegate : RCTAppDelegate<UIApplicationDelegate,UNUserNotificationCenterDelegate>

@end
```

{% tabs %}
{% tab title="Swift(APNs)" %}

```swift
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
  ...
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // =======================================================
    // 이 내용은 Wisetracker 기본 SDK가 이미 적용된 경우에는 새로 적용할
    // 필요가 없습니다.  메시징 서비스만 이용하는 경우 참조해주세요.
    // =======================================================
    // Start : Wisetracker SDK 호출
    DOT.initialization(launchOptions, application: application)
    #if DEBUG
      DOT.checkDebugMode(true)
    #else
      DOT.checkDebugMode(false)
    #endif
    // End : Wisetracker SDK init
    ...
    // =======================================================
    // Start : 푸시 권한 요청 <-- 새로 추가된 부분 (1/2)
    // =======================================================
    registerForRemoteNotifications() 
    // =======================================================
    // End : 푸시 권한 요청
    // =======================================================
    ...
  }
  ...
  // =======================================================
  // Start : 푸시 권한 요청 <-- 새로 추가된 부분 (2/2)
  // =======================================================
  // MARK: PushMessage: Regist
  private func registerForRemoteNotifications() {
    // 권한 요청
    let center = UNUserNotificationCenter.current()
    center.delegate = self // push처리에 대한 delegate - UNUserNotificationCenterDelegate
    let options: UNAuthorizationOptions = [.alert, .sound, .badge]
    center.requestAuthorization(options: options) { (granted, error) in
      guard granted else {
        return
      }
      DispatchQueue.main.async {
        UIApplication.shared.registerForRemoteNotifications()
      }
    }
  }
  // =======================================================
  // End : 푸시 권한 요청
  // =======================================================
}
```

{% endtab %}

{% tab title="Swift(FCM)" %}

```swift
import UIKit
import DOT
import Firebase
import UserNotifications


@main
class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        
        // WISETRACKER :  Firebase FCM 토큰 관련 설정을 위해서 필요한 코드.
        FirebaseApp.configure()
        Messaging.messaging().delegate = self
        
        // WISETRACKER :  userNotificationCenter 함수가 동작하기 위해서 추가하는 Delegate 설정. 이 코드가 없으면 userNotificationCenter 함수가 동작하지 않음.
        let center = UNUserNotificationCenter.current()
        center.delegate = self
         
        
        //  WISETRACKER : SDK 초기화
        DOT.initialization(nil, application: UIApplication.shared)
        #if DEBUG
          DOT.checkDebugMode(true)
        #else
          DOT.checkDebugMode(false)
        #endif
        // End : Wisetracker SDK 호출
        
        //  WISETRACKER : 푸시 알림 권한 요청
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
            guard granted else {
               return
             }
            print("푸시알림 권한이 true")
            // 푸시알림 권한이 true일때
             DispatchQueue.main.async {
                 // APNS 원격 알림 등록
                 application.registerForRemoteNotifications()
             }
        }
        
        return true
    }
}    
```

{% endtab %}

{% tab title="Objective-C(APNs)" %}

```objectivec
@implementation AppDelegate
...
- (Bool)application: (UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
  // =======================================================
  // 이 내용은 Wisetracker 기본 SDK가 이미 적용된 경우에는 새로 적용할
  // 필요가 없습니다.  메시징 서비스만 이용하는 경우 참조해주세요.
  // =======================================================
  // Start : Wisetracker SDK 호출
  [DOT initialization:nil application:[UIApplication sharedApplication]];
  #ifdef DEBUG
    [DOT checkDebugMode:true]
  #else
    [DOT checkDebugMode:false]
  #endif
  // End : Wisetracker SDK 호출
  ...
  // =======================================================
  // Start : 푸시 권한 요청
  // =======================================================
  UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
  center.delegate = self;

  [center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error) {
    
    if (!error) {
      //허용일 경우
      [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
  }];
  // =======================================================
  // End : 푸시 권한 요청
  // =======================================================

  ...
}
...
@end
```

{% endtab %}
{% endtabs %}

### Device Token 수집

Device token은 푸시 발송 시스템에서 메시지 전송시 수신 대상이 되는 개개인 별로 Unique하게 발급되는 일종의 식별ID 값입니다. Device token을 수집을 위해서 AppDelegate 에 정의된 **didRegisterForRemoteNotificationsWithDeviceToken()** 함수에 아래와 같이 분석 코드를 적용합니다

**`AppDelegate`**

{% tabs %}
{% tab title="Swift(APNs)" %}

```swift
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
  ...
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // =======================================================
    // 이 내용은 Wisetracker 기본 SDK가 이미 적용된 경우에는 새로 적용할
    // 필요가 없습니다.  메시징 서비스만 이용하는 경우 참조해주세요.
    // =======================================================
    // Start : Wisetracker SDK 호출
    DOT.initialization(launchOptions, application: application)
    #if DEBUG
      DOT.checkDebugMode(true)
    #else
      DOT.checkDebugMode(false)
    #endif
    // End : Wisetracker SDK init
    ...
    // =======================================================
    // Start : 푸시 권한 요청
    // =======================================================
    registerForRemoteNotifications() 
    // =======================================================
    // End : 푸시 권한 요청
    // =======================================================
    ...
  }
  ...
  // =======================================================
  // Start : 푸시 권한 요청
  // =======================================================
  // MARK: PushMessage: Regist
  private func registerForRemoteNotifications() {
    // 권한 요청
    let center = UNUserNotificationCenter.current()
    center.delegate = self // push처리에 대한 delegate - UNUserNotificationCenterDelegate
    let options: UNAuthorizationOptions = [.alert, .sound, .badge]
    center.requestAuthorization(options: options) { (granted, error) in
      guard granted else {
        return
      }
      DispatchQueue.main.async {
        UIApplication.shared.registerForRemoteNotifications()
      }
    }
  }
  // =======================================================
  // End : 푸시 권한 요청
  // =======================================================
  
  // =======================================================
  // Start : 푸시 토큰 등록 <-- 새로 추가된 부분
  // =======================================================
  func application(_ application: UIApplication,didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    ...
    let tokenParts = deviceToken.map { data -> String in
      return String(format: "%02.2hhx", data)
    }
    let token = tokenParts.joined()
    DOT.setPushToken(token)
    ...
  }
  // =======================================================
  // End : 푸시 토큰 등록
  // =======================================================
}
```

{% endtab %}

{% tab title="Swift(FCM)" %}

```swift
import UIKit
import DOT
import Firebase
import UserNotifications


@main
class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        
        // WISETRACKER :  Firebase FCM 토큰 관련 설정을 위해서 필요한 코드.
        FirebaseApp.configure()
        Messaging.messaging().delegate = self
        
        // WISETRACKER :  userNotificationCenter 함수가 동작하기 위해서 추가하는 Delegate 설정. 이 코드가 없으면 userNotificationCenter 함수가 동작하지 않음.
        let center = UNUserNotificationCenter.current()
        center.delegate = self
         
        
        //  WISETRACKER : SDK 초기화
        DOT.initialization(nil, application: UIApplication.shared)
        #if DEBUG
          DOT.checkDebugMode(true)
        #else
          DOT.checkDebugMode(false)
        #endif
        // End : Wisetracker SDK 호출
        
        //  WISETRACKER : 푸시 알림 권한 요청
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
            guard granted else {
               return
             }
            print("푸시알림 권한이 true")
            // 푸시알림 권한이 true일때
             DispatchQueue.main.async {
                 // APNS 원격 알림 등록
                 application.registerForRemoteNotifications()
             }
        }
        
        return true
    }
    
     //  WISETRACKER : APNs 토큰을 등록한 후 FCM 토큰 가져오기
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        
        // APNs 토큰을 FCM에 설정
        Messaging.messaging().apnsToken = deviceToken

        // APNs 토큰이 등록된 후 FCM 토큰 가져오기
        Messaging.messaging().token { token, error in
            if let error = error {
                print("Error fetching FCM registration token: \(error)")
            } else if let token = token {
                print("FCM registration token ( didRegisterForRemoteNotificationsWithDeviceToken22 ) : \(token)")
                DOT.setPushToken(token) // 토큰 저장
            }
        }
    }
}    
```

{% endtab %}

{% tab title="Objective-C(APNs)" %}

```objectivec
@implementation AppDelegate
...
- (Bool)application: (UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
  // =======================================================
  // 이 내용은 Wisetracker 기본 SDK가 이미 적용된 경우에는 새로 적용할
  // 필요가 없습니다.  메시징 서비스만 이용하는 경우 참조해주세요.
  // =======================================================
  // Start : Wisetracker SDK 호출
  [DOT initialization:nil application:[UIApplication sharedApplication]];
  #ifdef DEBUG
    [DOT checkDebugMode:true]
  #else
    [DOT checkDebugMode:false]
  #endif
  // End : Wisetracker SDK 호출
  ...
  // =======================================================
  // Start : 푸시 권한 요청
  // =======================================================
  UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
  center.delegate = self;

  [center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error) {
    
    if (!error) {
      //허용일 경우
      [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
  }];
  // =======================================================
  // End : 푸시 권한 요청
  // =======================================================

  ...
}
...

// =======================================================
// Start : 푸시 토큰 등록 <-- 새로 추가된 부분
// =======================================================
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  ...
  const unsigned char *dataBuffer = (const unsigned char *)deviceToken.bytes;
  NSMutableString *hexString  = [NSMutableString stringWithCapacity:(deviceToken.length * 2)];
  for (int i = 0; i < deviceToken.length; ++i) {
      [hexString appendFormat:@"%02x", dataBuffer[i]];
  }
  NSString *deviceTokenStr = [hexString copy];
  [DOT setPushToken:deviceTokenStr];
  ...
}
// =======================================================
// End : 푸시 토큰 등록
// =======================================================
...
@end
```

{% endtab %}
{% endtabs %}

### 푸시메세지 클릭 측정

* 수신된 푸시 메시지를 클릭하여 앱이 실행된 오픈수 분석을 위하여 아래와 같이 추가합니다.&#x20;

#### **`AppDelegate`**

{% tabs %}
{% tab title="Swift(APNs)" %}

```swift
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
  ...
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // =======================================================
    // 이 내용은 Wisetracker 기본 SDK가 이미 적용된 경우에는 새로 적용할
    // 필요가 없습니다.  메시징 서비스만 이용하는 경우 참조해주세요.
    // =======================================================
    // Start : Wisetracker SDK 호출
    DOT.initialization(launchOptions, application: application)
    #if DEBUG
      DOT.checkDebugMode(true)
    #else
      DOT.checkDebugMode(false)
    #endif
    // End : Wisetracker SDK init
    ...
    // =======================================================
    // Start : 푸시 권한 요청
    // =======================================================
    registerForRemoteNotifications() 
    // =======================================================
    // End : 푸시 권한 요청
    // =======================================================
    ...
  }
  ...
  // =======================================================
  // Start : 푸시 권한 요청
  // =======================================================
  // MARK: PushMessage: Regist
  private func registerForRemoteNotifications() {
    // 권한 요청
    let center = UNUserNotificationCenter.current()
    center.delegate = self // push처리에 대한 delegate - UNUserNotificationCenterDelegate
    let options: UNAuthorizationOptions = [.alert, .sound, .badge]
    center.requestAuthorization(options: options) { (granted, error) in
      guard granted else {
        return
      }
      DispatchQueue.main.async {
        UIApplication.shared.registerForRemoteNotifications()
      }
    }
  }
  // =======================================================
  // End : 푸시 권한 요청
  // =======================================================
  
  // =======================================================
  // Start : 푸시 토큰 등록
  // =======================================================
  func application(_ application: UIApplication,didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    ...
    let tokenParts = deviceToken.map { data -> String in
      return String(format: "%02.2hhx", data)
    }
    let token = tokenParts.joined()
    DOT.setPushToken(token)
    ...
  }
  // =======================================================
  // End : 푸시 토큰 등록
  // =======================================================
  
  // =======================================================
  // Start : 푸시 클릭 <-- 새롭게 추가된 부분
  // =======================================================
  func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    ...
    DOT.setPushClick(response.notification.request.content.userInfo, application: UIApplication.shared)
    ...
    completionHandler()
  }
  // =======================================================
  // End : 푸시 클릭
  // =======================================================
}
```

{% endtab %}

{% tab title="Swift(FCM)" %}

```swift
import UIKit
import DOT
import Firebase
import UserNotifications


@main
class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate {

    // WISETRACKER :  푸시 메시지 클릭시 DOT.pushClick 함수 호출
    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        didReceive response: UNNotificationResponse,
        withCompletionHandler completionHandler: @escaping () -> Void
    ) {
            print("setPushClickStart")
            let userInfo = response.notification.request.content.userInfo
            if(userInfo != nil){
                DOT.setPushClick(NSDictionary(dictionary:userInfo) as! [AnyHashable : Any], application: UIApplication.shared)
            }
            print("setPushClickEnd")
            completionHandler()
    }

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        
        // WISETRACKER :  Firebase FCM 토큰 관련 설정을 위해서 필요한 코드.
        FirebaseApp.configure()
        Messaging.messaging().delegate = self
        
        // WISETRACKER :  userNotificationCenter 함수가 동작하기 위해서 추가하는 Delegate 설정. 이 코드가 없으면 userNotificationCenter 함수가 동작하지 않음.
        let center = UNUserNotificationCenter.current()
        center.delegate = self
         
        
        //  WISETRACKER : SDK 초기화
        DOT.initialization(nil, application: UIApplication.shared)
        #if DEBUG
          DOT.checkDebugMode(true)
        #else
          DOT.checkDebugMode(false)
        #endif
        // End : Wisetracker SDK 호출
        
        //  WISETRACKER : 푸시 알림 권한 요청
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
            guard granted else {
               return
             }
            print("푸시알림 권한이 true")
            // 푸시알림 권한이 true일때
             DispatchQueue.main.async {
                 // APNS 원격 알림 등록
                 application.registerForRemoteNotifications()
             }
        }
        
        return true
    }
    
     //  WISETRACKER : APNs 토큰을 등록한 후 FCM 토큰 가져오기
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        
        // APNs 토큰을 FCM에 설정
        Messaging.messaging().apnsToken = deviceToken

        // APNs 토큰이 등록된 후 FCM 토큰 가져오기
        Messaging.messaging().token { token, error in
            if let error = error {
                print("Error fetching FCM registration token: \(error)")
            } else if let token = token {
                print("FCM registration token ( didRegisterForRemoteNotificationsWithDeviceToken22 ) : \(token)")
                DOT.setPushToken(token) // 토큰 저장
            }
        }
    }
}    
```

{% endtab %}

{% tab title="Objective-C(APNs)" %}

```objectivec
@implementation AppDelegate
...
- (Bool)application: (UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
  // =======================================================
  // 이 내용은 Wisetracker 기본 SDK가 이미 적용된 경우에는 새로 적용할
  // 필요가 없습니다.  메시징 서비스만 이용하는 경우 참조해주세요.
  // =======================================================
  // Start : Wisetracker SDK 호출
  [DOT initialization:nil application:[UIApplication sharedApplication]];
  #ifdef DEBUG
    [DOT checkDebugMode:true]
  #else
    [DOT checkDebugMode:false]
  #endif
  // End : Wisetracker SDK 호출
  ...
  // =======================================================
  // Start : 푸시 권한 요청
  // =======================================================
  UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
  center.delegate = self;

  [center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error) {
    
    if (!error) {
      //허용일 경우
      [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
  }];
  // =======================================================
  // End : 푸시 권한 요청
  // =======================================================

  ...
}
...

// =======================================================
// Start : 푸시 토큰 등록
// =======================================================
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  ...
  const unsigned char *dataBuffer = (const unsigned char *)deviceToken.bytes;
  NSMutableString *hexString  = [NSMutableString stringWithCapacity:(deviceToken.length * 2)];
  for (int i = 0; i < deviceToken.length; ++i) {
      [hexString appendFormat:@"%02x", dataBuffer[i]];
  }
  NSString *deviceTokenStr = [hexString copy];
  [DOT setPushToken:deviceTokenStr];
  ...
}
// =======================================================
// End : 푸시 토큰 등록
// =======================================================

// =======================================================
// Start : 푸시 클릭 <-- 새롭게 추가된 부분
// =======================================================
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler  API_AVAILABLE(ios(10.0)){
  ...
  NSDictionary *userInfo = response.notification.request.content.userInfo;
  [DOT setPushClick:userInfo application:UIApplication.sharedApplication];
  ...
  completionHandler();
}
// =======================================================
// End : 푸시 클릭
// =======================================================
...
@end
```

{% endtab %}
{% endtabs %}

## 이미지 푸시메시지 적용(선택)

### Notification Service Extension Target 추가

이미지를 포함한 푸시메세를 수신받기 위해 필요합니다.

File - New - Target 메뉴에서 "`Notification Service Extension`"을 선택합니다.

<figure><img src="https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2Fd3utwKheiUQjbqs9Cq7S%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202023-09-08%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%209.32.02.png?alt=media&#x26;token=359402f6-8b7b-4e60-85bf-e267541c139f" alt=""><figcaption></figcaption></figure>

Product Name에 타겟명을 입력합니다. (아래에서 Podfile에 target을 추가할때 사용할 타겟명입니다)

<figure><img src="https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2F7QevHyg3KrMKqxNfS9GY%2Fimage.png?alt=media&#x26;token=a1b9dbc1-514e-48b1-9d7c-70400e0d3f5a" alt=""><figcaption></figcaption></figure>

Finish 버튼 클릭 후 아래와 같은 `NotificationServiceExtension` 폴더가 생성됩니다.

<div align="left" data-full-width="false"><img src="https://423922975-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M_ZKcnBFmefw9Yfed6b%2F-Mj3I28eMLtVX6OGWTYg%2F-Mj3JS6M5-bngvUxKq73%2FnotificationServiceExtension.png?alt=media&#x26;token=613634ed-343d-41cd-8906-d2411fb91079" alt=""></div>

### Podfile 수정

Podfile에 아래와 같이 이미지 푸시를 위한 타겟을 추가한 후 pod install 명령어를 실행시켜 줍니다.

#### **`Podfile`**

```markup
target 'wisetracker' do
  ...
  # S: Wisetracker SDK add
  pod 'RW'
  # E: Wisetracker SDK add
  ...
end
...

# =======================================================
# Start : 이미지 푸시를 위한 추가
# =======================================================
target 'NotificationServiceExtension' do
  use_frameworks!
  ### 만약 Wisetracker SDK 의 버전이 명시되어 있는 경우 동일하게 버전을 명시 해 주세요.
  pod 'RW'
end
# =======================================================
# End : 이미지 푸시
# =======================================================
...
...
```

위의 "<mark style="color:red;">NotificationServiceExtension</mark>"은 고객사에서 만든 타켓명으로 해주셔야 합니다.&#x20;

예시는 타겟명이 "NotificationServiceExtension"인 경우입니다.

### NotificationService 수정

* `NotificationService` 파일을 열어 아래의 내용으로 대체해 주세요.\ <mark style="color:red;">**\* 기존 내용을 모두 삭제하고 아래 내용으로 대체하는것이며, 추가가 아님에 유의 해 주세요.**</mark>

**`NotificationService`**

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

```swift
// =======================================================
// Start : 소스코드 모두 바꾸기
// =======================================================
import UserNotifications
import DOT
class NotificationService: UNNotificationServiceExtension {
    var contentHandler: ((UNNotificationContent) -> Void)?
    var receivedRequest: UNNotificationRequest!
    var bestAttemptContent: UNMutableNotificationContent!
    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.receivedRequest = request
        self.contentHandler = contentHandler
        self.bestAttemptContent = DOT.didReceiveNotificationExtensionRequest(request, with: bestAttemptContent)
        if let bestAttemptContent = self.bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }
    override func serviceExtensionTimeWillExpire() {
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }
}
// =======================================================
// End : 소스코드 모두 바꾸기
// =======================================================
```

{% endtab %}

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

```objectivec
// =======================================================
// Start : 소스코드 모두 바꾸기
// =======================================================
#import "NotificationService.h"
#import <DOT/DOT.h>
@interface NotificationService ()
@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
@end
@implementation NotificationService
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];
    self.bestAttemptContent = [DOT didReceiveNotificationExtensionRequest:request withContent:self.bestAttemptContent];
    self.contentHandler(self.bestAttemptContent);
}
- (void)serviceExtensionTimeWillExpire {
    self.contentHandler(self.bestAttemptContent);
}
@end
// =======================================================
// End : 소스코드 모두 바꾸기
// =======================================================
```

{% endtab %}
{% endtabs %}

## 동영상 Push 적용(선택)

### Notification Content Extension Target 추가

동영상을 포함한 Push를 확장했을 때 Push 화면영역 내에서 동영상 실행을 위해 필요합니다.

File - New - Target 메뉴에서 `Notification Content Extension` 선택합니다.

<figure><img src="https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2FZCWT5TvOwRDWmM7l0up4%2Fimage.png?alt=media&#x26;token=a0a003e6-1c7f-4b50-8619-62b808e422af" alt=""><figcaption></figcaption></figure>

Product Name에 타겟명을 입력합니다. (아래에서 Podfile에 target을 추가할때 사용할 타겟명입니다)

<figure><img src="https://423922975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_ZKcnBFmefw9Yfed6b-3102695190%2Fuploads%2FOodsrx9fzi6nX8vDNImi%2Fimage.png?alt=media&#x26;token=3aa49ea1-dd6d-49b1-b042-616c28d0644f" alt=""><figcaption></figcaption></figure>

추가 완료 시 아래와 같은 폴더가 생성됩니다.

<div align="left"><img src="https://423922975-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M_ZKcnBFmefw9Yfed6b%2F-Mj3I28eMLtVX6OGWTYg%2F-Mj3KLp6JpJciUjiBirC%2FnotificationContentExtension1.png?alt=media&#x26;token=ea69e99b-57a9-41f4-8462-0e704330dc3f" alt=""></div>

### 기존파일 대체

{% hint style="warning" %}
*<mark style="color:red;">**이 작업은 파인더를 이용해서 진행해주세요, XCode에서 복사/붙여넣기 하면 제대로 복사되지 않습니다**</mark>*&#x20;
{% endhint %}

Pods/RW/Resources 경로 아래 **Base.lproj** 폴더와, **NotificationViewController** 파일을 복사하여, 새로 생성한 `NotificationContentExtension` 폴더의 동일한 파일에 덮어 씌워 줍니다.&#x20;

<div align="left"><img src="https://423922975-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M_ZKcnBFmefw9Yfed6b%2F-Mj3I28eMLtVX6OGWTYg%2F-Mj3KUXgFQ0lpyW9V4os%2FvideoPush_file.png?alt=media&#x26;token=b89b6672-6236-42d5-9b04-28b8ddf0b88a" alt=""></div>

### info.plist 파일 수정

`NSExtensionAttributes` 키값을 찾아 아래와 같이 replace해줍니다.

#### **`info.plist`**

```markup
...
<!--
=======================================================
Start : 동영상 푸시 
=======================================================
-->
<key>NSExtensionAttributes</key>
<dict>
    <key>UNNotificationExtensionCategory</key>
    <array>
        <string>RWVideoPush</string>
    </array>
    <key>UNNotificationExtensionDefaultContentHidden</key>
    <false/>
    <key>UNNotificationExtensionInitialContentSizeRatio</key>
    <real>0.4</real>
    <key>UNNotificationExtensionOverridesDefaultTitle</key>
    <false/>
    <key>UNNotificationExtensionUserInteractionEnabled</key>
    <false/>
</dict>
<!--
=======================================================
End : 동영상 푸시
=======================================================
-->
...
```

### Podfile 수정

아래와 같이 YouTubePlayer 라이브러리(동영상 실행을 위한 라이브러리)를 추가하고, pod install를 실행합니다.

아래의 "<mark style="color:red;">NotificationContentExtension</mark>"은 고객사에서 만든 타켓명으로 해주셔야 합니다. 예시는 타겟명이 "<mark style="color:red;">NotificationContentExtension</mark>"인 경우입니다.

#### **`Podfile`**

<pre class="language-markup"><code class="lang-markup">...
target 'wisetracker' do
  ...
  # S: Wisetracker SDK add
  pod 'RW'
  pod 'Firebase/Messaging'
  # E: Wisetracker SDK add
  ...
end
...

<strong># =======================================================
</strong># Start : 동영상 푸시 
# =======================================================
target 'NotificationContentExtension' do
  pod 'YouTubePlayer'
end
# =======================================================
# End : 동영상 푸시
# =======================================================
...
</code></pre>

### 푸시 수신동의

푸시발송은 기본 적용에서는 "수신거부"입니다. 아래 링크를 참조하여 화면에서 수신동의/거부를 진행 후 해당 데이터를 "태깅"작업을 통해 남겨주세요.

{% embed url="<https://document.wisetracker.co.kr/v2-developer/in-app-event/event-list/messaging#push_noti_authorized>" %}

## 축하합니다.

이제 iOS SDK 설정이 완료되었습니다.
