# iOS 모달 리치 미디어

Pushwoosh SDK 버전 6.7.5부터 **모달 리치 미디어**를 전송할 수 있습니다.

사용자 정의할 수 있는 새로운 **모달 리치 미디어**를 소개합니다. 새로운 모달 리치 미디어는 화면을 완전히 가리지 않으며 화면의 다른 부분(상단, 하단, 중앙)에 배치할 수 있습니다.

> 리치 미디어 페이지에 대한 자세한 내용은 [가이드](/ko/product/content/rich-media)를 참조하십시오.

## 구성

<Aside type="note">
 기본적으로 Pushwoosh iOS SDK는 레거시 리치 미디어 표시를 지원합니다.
</Aside>

<Aside type="note">
Customer Journey Builder에서 인앱 메시지로 모달 리치 미디어 표시를 사용하려는 경우, 아래 표시된 코드를 구현했는지 확인하십시오. 자세한 내용은 [기본 SDK 통합](/ko/developer/pushwoosh-sdk/ios-sdk/setting-up-pushwoosh-ios-sdk/basic-integration-guide/)을 참조하십시오.
</Aside>

```swift
// 자동 푸시 알림용
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    Pushwoosh.configure.handlePushReceived(userInfo)
    completionHandler(.noData)
}
```

### 옵션 1: Info.plist 구성

모달 리치 미디어 표시를 활성화하려면 **info.plist**에서 `Pushwoosh_RICH_MEDIA_STYLE` 매개변수를 설정하고 `MODAL_RICH_MEDIA` 값을 할당하십시오.

**Info.plist**:
```xml
<key>Pushwoosh_RICH_MEDIA_STYLE</key>
<string>MODAL_RICH_MEDIA</string>
```

### 옵션 2: 프로그래밍 방식 구성 (SDK 7.0.14 이상)

<Aside type="tip">
Pushwoosh iOS SDK 버전 **7.0.14**부터 사용 가능합니다.
</Aside>

AppDelegate에서 프로그래밍 방식으로 리치 미디어 표시 스타일을 구성할 수도 있습니다:

<Tabs>
<TabItem label="Swift">
```swift
func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    // 모달 표시 스타일 설정
    Pushwoosh.media.setRichMediaPresentationStyle(.modal)

    // 모달 창 모양 구성
    Pushwoosh.media.modalRichMedia.configure(
        position: .PWModalWindowPositionBottom,
        presentAnimation: .PWAnimationPresentFromBottom,
        dismissAnimation: .PWAnimationDismissDown
    )

    Pushwoosh.configure.registerForPushNotifications()
    return true
}
```
</TabItem>
<TabItem label="Objective-C">
```objective-c
- (BOOL)application:(UIApplication *)application
        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // 모달 표시 스타일 설정
    [[Pushwoosh media] setRichMediaPresentationStyle:PWRichMediaPresentationStyleModal];

    // 모달 창 모양 구성
    [[[Pushwoosh media] modalRichMedia] configureWithPosition:PWModalWindowPositionBottom
                                             presentAnimation:PWAnimationPresentFromBottom
                                             dismissAnimation:PWAnimationDismissDown];

    [[Pushwoosh configure] registerForPushNotifications];
    return YES;
}
```
</TabItem>
</Tabs>

기본적으로 모달 리치 미디어는 화면 중앙에 아래에서 위로 나타나는 애니메이션과 함께 표시됩니다.

<div style={{ display: "flex", justifyContent: "center" }}>
<video src="/ios-push-notifications-ios-modal-rich-media-1.webm" title="예시" autoplay loop muted playsinline width="300" />
</div>

### 모달 리치 미디어 위치 지정

모달 리치 미디어는 화면의 다른 위치에 배치할 수 있습니다.

```objective-c
/**
 모달 창을 표시할 수 있는 위치를 정의하는 열거형입니다.

 - `PWModalWindowPositionTop`: 모달 창이 화면 상단, 안전 영역 내에 나타납니다.
 - `PWModalWindowPositionCenter`: 모달 창이 화면 중앙, 안전 영역 내에 나타납니다.
 - `PWModalWindowPositionBottom`: 모달 창이 화면 하단, 안전 영역 내에 나타납니다.
 - `PWModalWindowPositionBottomSheet`: 모달 창이 화면 맨 아래, 안전 영역을 무시하고 나타납니다.
 - `PWModalWindowPositionDefault`: 기본 위치는 화면 중앙, 안전 영역 내입니다.
 */
typedef NS_ENUM(NSInteger, ModalWindowPosition) {
    PWModalWindowPositionTop,       // 화면 상단에 표시 (안전 영역 내)
    PWModalWindowPositionCenter,    // 화면 중앙에 표시 (안전 영역 내)
    PWModalWindowPositionBottom,    // 화면 하단에 표시 (안전 영역 내)
    PWModalWindowPositionBottomSheet, // 화면 맨 아래에 표시 (안전 영역 무시)
    PWModalWindowPositionFullScreen, // 전체 화면, 안전 영역 인셋 무시
    PWModalWindowPositionDefault    // 기본 위치 (화면 중앙, 안전 영역 내)
};
```

아래 예시는 화면 상단에 표시된 모달 리치 미디어를 보여줍니다.

<div style={{ display: "flex", justifyContent: "center" }}>
<video src="/ios-push-notifications-ios-modal-rich-media-2.webm" title="예시" autoplay loop muted playsinline width="300" />
</div>

모달 리치 미디어 표시 애니메이션은 다음과 같습니다:

```objective-c
typedef NS_ENUM(NSInteger, PresentModalWindowAnimation) {
    PWAnimationPresentFromBottom,
    PWAnimationPresentFromTop,
    PWAnimationPresentFromRight,
    PWAnimationPresentFromLeft,
    PWAnimationPresentNone
};
```

모달 리치 미디어 닫기 애니메이션은 다음과 같습니다:

```objective-c
typedef NS_ENUM(NSInteger, DismissModalWindowAnimation) {
    PWAnimationDismissDown,
    PWAnimationDismissUp,
    PWAnimationDismissLeft,
    PWAnimationDismissRight,
    PWAnimationCurveEaseInOut,
    PWAnimationDismissNone,

    /**
     * 기본 닫기 애니메이션은 `PWAnimationCurveEaseInOut`입니다.
     */
    PWAnimationDismissDefault
};
```

아래 예시는 왼쪽에서 오른쪽으로 나타나는 표시 애니메이션과 오른쪽으로 닫히는 애니메이션으로 화면 하단에 모달 리치 미디어를 표시하는 것을 보여줍니다:

<div style={{ display: "flex", justifyContent: "center" }}>
<video src="/ios-push-notifications-ios-modal-rich-media-3.webm" title="예시" autoplay loop muted playsinline width="300" />
</div>

### 모달 리치 미디어의 추가 매개변수

<Aside type="tip">
다음 API는 Pushwoosh iOS SDK 버전 **7.0.14**부터 사용 가능합니다.
</Aside>

모달 리치 미디어를 표시하기 위한 추가 매개변수에는 진동 유형의 햅틱 피드백 추가, 스와이프 제스처 활성화, 지정된 시간 후 자동 닫기 타이머 설정과 같은 옵션이 포함됩니다.

<Tabs>
<TabItem label="Swift">
```swift
// 햅틱 피드백 유형
Pushwoosh.media.modalRichMedia.setHapticFeedbackType(.PWHapticFeedbackLight)

// 닫기 위한 스와이프 방향
Pushwoosh.media.modalRichMedia.setDismissSwipeDirections([
    NSNumber(value: DismissSwipeDirection.PWSwipeDismissDown.rawValue),
    NSNumber(value: DismissSwipeDirection.PWSwipeDismissUp.rawValue)
])

// 리치 미디어 모서리 반경 설정
let topCorners = PWCornerTypeTopLeft.rawValue | PWCornerTypeTopRight.rawValue
Pushwoosh.media.modalRichMedia.setCornerType(CornerType(rawValue: topCorners), withRadius: 16)

// N초 후 모달 리치 미디어 닫기
Pushwoosh.media.modalRichMedia.closeAfter(3)
```
</TabItem>
<TabItem label="Objective-C">
```objective-c
// 햅틱 피드백 유형
[[[Pushwoosh media] modalRichMedia] setHapticFeedbackType:PWHapticFeedbackLight];

// 닫기 위한 스와이프 방향
[[[Pushwoosh media] modalRichMedia] setDismissSwipeDirections:@[
    @(PWSwipeDismissDown),
    @(PWSwipeDismissUp)
]];

// 리치 미디어 모서리 반경 설정
CornerType topCorners = PWCornerTypeTopLeft | PWCornerTypeTopRight;
[[[Pushwoosh media] modalRichMedia] setCornerType:topCorners withRadius:16.0];

// N초 후 모달 리치 미디어 닫기
[[[Pushwoosh media] modalRichMedia] closeAfter:3.0];
```
</TabItem>
</Tabs>

**햅틱 피드백 유형:**

```objective-c
typedef NS_ENUM(NSInteger, HapticFeedbackType) {
    PWHapticFeedbackLight,         // 가벼운 진동 피드백
    PWHapticFeedbackMedium,        // 중간 진동 피드백
    PWHapticFeedbackHard,          // 강한 진동 피드백
    PWHapticFeedbackNone           // 진동 꺼짐 (기본값)
};
```

**스와이프 방향:**

```objective-c
typedef NS_ENUM(NSInteger, DismissSwipeDirection) {
    PWSwipeDismissDown,
    PWSwipeDismissUp,
    PWSwipeDismissLeft,
    PWSwipeDismissRight,
    PWSwipeDismissNone
};
```

## PWRichMediaPresentingDelegate

<Aside type="tip">
`Pushwoosh.media.modalRichMedia.delegate`를 통한 델리게이트 API는 SDK 버전 **7.0.14**부터 사용 가능합니다.
</Aside>

모달 리치 미디어의 큐를 관리하려면 `PWRichMediaPresentingDelegate`의 델리게이트 메서드를 구현해야 합니다.
이 기능을 사용하면 모달 리치 미디어가 순차적으로 표시되며, 사용자가 현재 미디어를 닫을 때까지 다음 미디어가 표시되지 않습니다. 사용자가 표시된 리치 미디어를 닫으면 다른 푸시 알림의 일부였던 다음 리치 미디어가 표시됩니다.

<Tabs>
<TabItem label="Swift">
```swift
import UIKit
import PushwooshFramework

@main
class AppDelegate: UIResponder, UIApplicationDelegate, PWRichMediaPresentingDelegate {

    var richMediaQueue: [PWRichMedia] = []
    var isPresenting = false

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

        // 모달 리치 미디어 구성
        Pushwoosh.media.setRichMediaPresentationStyle(.modal)
        Pushwoosh.media.modalRichMedia.configure(
            position: .PWModalWindowPositionBottom,
            presentAnimation: .PWAnimationPresentFromBottom,
            dismissAnimation: .PWAnimationDismissDown
        )

        // 델리게이트 설정
        Pushwoosh.media.modalRichMedia.delegate = self

        Pushwoosh.configure.registerForPushNotifications()
        return true
    }

    // MARK: - PWRichMediaPresentingDelegate

    func richMediaManager(_ richMediaManager: PWRichMediaManager, shouldPresent richMedia: PWRichMedia) -> Bool {
        if !richMediaQueue.contains(where: { $0 === richMedia }) {
            richMediaQueue.append(richMedia)
        }
        return !isPresenting
    }

    func richMediaManager(_ richMediaManager: PWRichMediaManager, didPresent richMedia: PWRichMedia) {
        isPresenting = true
    }

    func richMediaManager(_ richMediaManager: PWRichMediaManager, didClose richMedia: PWRichMedia) {
        isPresenting = false

        if let idx = richMediaQueue.firstIndex(where: { $0 === richMedia }) {
            richMediaQueue.remove(at: idx)
        }

        // 큐의 다음 리치 미디어 표시
        if let nextRichMedia = richMediaQueue.first {
            Pushwoosh.media.modalRichMedia.present(nextRichMedia)
        }
    }

    func richMediaManager(_ richMediaManager: PWRichMediaManager, presentingDidFailFor richMedia: PWRichMedia, withError error: Error) {
        richMediaManager(richMediaManager, didClose: richMedia)
    }
}
```
</TabItem>
<TabItem label="Objective-C">
```objective-c
#import "AppDelegate.h"
#import <PushwooshFramework/PushwooshFramework.h>

@interface AppDelegate () <PWRichMediaPresentingDelegate>

@property (nonatomic, strong) NSMutableArray<PWRichMedia *> *richMediaQueue;
@property (nonatomic, assign) BOOL isPresenting;

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    self.richMediaQueue = [NSMutableArray array];
    self.isPresenting = NO;

    // 모달 리치 미디어 구성
    [[Pushwoosh media] setRichMediaPresentationStyle:PWRichMediaPresentationStyleModal];
    [[[Pushwoosh media] modalRichMedia] configureWithPosition:PWModalWindowPositionBottom
                                             presentAnimation:PWAnimationPresentFromBottom
                                             dismissAnimation:PWAnimationDismissDown];

    // 델리게이트 설정
    [[[Pushwoosh media] modalRichMedia] setDelegate:self];

    [[Pushwoosh configure] registerForPushNotifications];
    return YES;
}

#pragma mark - PWRichMediaPresentingDelegate

- (BOOL)richMediaManager:(PWRichMediaManager *)richMediaManager shouldPresentRichMedia:(PWRichMedia *)richMedia {
    if (![self.richMediaQueue containsObject:richMedia]) {
        [self.richMediaQueue addObject:richMedia];
    }
    return !self.isPresenting;
}

- (void)richMediaManager:(PWRichMediaManager *)richMediaManager didPresentRichMedia:(PWRichMedia *)richMedia {
    self.isPresenting = YES;
}

- (void)richMediaManager:(PWRichMediaManager *)richMediaManager didCloseRichMedia:(PWRichMedia *)richMedia {
    self.isPresenting = NO;

    [self.richMediaQueue removeObject:richMedia];

    // 큐의 다음 리치 미디어 표시
    if (self.richMediaQueue.count > 0) {
        [[[Pushwoosh media] modalRichMedia] presentRichMedia:self.richMediaQueue.firstObject];
    }
}

- (void)richMediaManager:(PWRichMediaManager *)richMediaManager presentingDidFailForRichMedia:(PWRichMedia *)richMedia withError:(NSError *)error {
    [self richMediaManager:richMediaManager didCloseRichMedia:richMedia];
}

@end
```
</TabItem>
</Tabs>