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

# 리워드 비디오 광고

> DARO를 통해 리워드 비디오 광고를 구현하는 방법을 알아봅니다.

## 리워드 비디오 형태 소개

* 광고 시청을 대가로 인앱 가치를 지닌 보상(재화, 기능, 컨텐츠 등)을 제공하는 형태의 광고입니다.
* 보상을 대가로 시청하므로 동영상 광고의 스킵이 불가능하며 일반적인 길이는 30초입니다.

<img src="https://mintcdn.com/delightroom-5a71a6a8/dxU0bpsPoPvkYh_g/sdk-integration/common-img/ad-formats/rv-example-image.png?fit=max&auto=format&n=dxU0bpsPoPvkYh_g&q=85&s=42c4b8429cf25ce598c679e6eee00f70" alt="Rv Example Image Pn" title="Rv Example Image Pn" style={{ width:"37%" }} width="1080" height="2336" data-path="sdk-integration/common-img/ad-formats/rv-example-image.png" />

### How It Works

<img src="https://mintcdn.com/delightroom-5a71a6a8/dxU0bpsPoPvkYh_g/sdk-integration/common-img/ad-formats/rv-example-gif.gif?s=e6a8679d28bbe4600a449121ba4bbe53" alt="Rv Example Gif Gi" title="Rv Example Gif Gi" style={{ width:"38%" }} width="180" height="389" data-path="sdk-integration/common-img/ad-formats/rv-example-gif.gif" />

***

## 광고 단위 설정

대시보드에서 발급받은 `ad unit ID`를 사용하여 광고 단위를 설정하세요.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    let rewardAdUnit = DaroAdUnit(unitId: "your_rewarded_unit_id")
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objc theme={null}
    // Objective-C에서는 초기화 시 unitId를 직접 전달합니다
    NSString *rewardedUnitId = @"your_rewarded_unit_id";
    ```
  </Tab>
</Tabs>

## 광고 구현

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    class ExampleViewController: UIViewController {
        private var daroRewardedAd: DaroRewardedAd? = nil
        let daroRewardedLoader = DaroRewardedAdLoader(unit: rewardAdUnit)

        override func viewDidLoad() {
            super.viewDidLoad()
            setupRewardedAd()
        }

        private func setupRewardedAd() {
            // 광고 로드 성공 리스너
            daroRewardedLoader.listener.onAdLoadSuccess = { [weak self] ad, adInfo in
                print("[DARO] Listener Reward Ad loaded: \(ad) \(adInfo)")
                self?.showAd(ad: ad)
            }

            // 광고 클릭 리스너
            daroRewardedLoader.listener.onAdClicked = { adInfo in
                print("[DARO] Listener Reward Ad clicked: \(adInfo)")
            }

            // 광고 노출 리스너
            daroRewardedLoader.listener.onAdImpression = { adInfo in
                print("[DARO] Listener Reward Ad impression: \(adInfo)")
            }

            // 광고 로드 실패 리스너
            daroRewardedLoader.listener.onAdLoadFail = { error in
                print("[DARO] Listener Reward Ad failed: \(error)")
            }

            daroRewardedLoader.loadAd()
        }

        private func showAd(ad: DaroRewardedAd) {
            self.daroRewardedAd = ad

            // 보상 획득 리스너
            self.daroRewardedAd?.rewardedAdListener.onEarnedReward = { adInfo, rewardedItem in
                print("[DARO] Listener Reward Ad earned: \(adInfo) \(rewardedItem)")
            }

            // 광고 표시 성공 리스너
            self.daroRewardedAd?.rewardedAdListener.onShown = { adInfo in
                print("[DARO] Listener Reward Ad shown: \(adInfo)")
            }

            // 광고 닫힘 리스너
            self.daroRewardedAd?.rewardedAdListener.onDismiss = { adInfo in
                print("[DARO] Listener Reward Ad dismissed: \(adInfo)")
            }

            // 광고 표시 실패 리스너
            self.daroRewardedAd?.rewardedAdListener.onFailedToShow = { adInfo, error in
                print("[DARO] Listener Reward Ad failed to show: \(adInfo) \(error)")
            }

            showRewardedAd()
        }

        private func showRewardedAd() {
            daroRewardedAd?.show(viewController: self)
        }
    }
    ```
  </Tab>

  <Tab title="Objective-C">
    **1. 헤더 파일에서 delegate 프로토콜 채택:**

    ```objc theme={null}
    @interface ExampleViewController () <DaroObjCRewardedAdDelegate>
    @property (nonatomic, strong) DaroObjCRewardedAd *rewardedAd;
    @end
    ```

    **2. 리워드 비디오 광고 설정 및 로드:**

    ```objc theme={null}
    - (void)setupRewardedAd {
        self.rewardedAd = [[DaroObjCRewardedAd alloc]
            initWithAdUnitId:@"your_rewarded_unit_id"];
        self.rewardedAd.delegate = self;

        // 광고 로드
        [self.rewardedAd load];
    }
    ```

    **3. Delegate 메서드 구현:**

    ```objc theme={null}
    #pragma mark - DaroObjCRewardedAdDelegate

    - (void)rewardedAdDidLoad:(DaroObjCRewardedAd *)ad
                       adInfo:(DaroObjCAdInfo *)adInfo {
        NSLog(@"[DARO] Rewarded ad loaded - Unit: %@", adInfo.adUnitId);
    }

    - (void)rewardedAdDidFail:(DaroObjCRewardedAd *)ad
                       toLoad:(NSError *)error {
        NSLog(@"[DARO] Failed to load: %@", error.localizedDescription);
    }

    - (void)rewardedAdDidShow:(DaroObjCRewardedAd *)ad
                       adInfo:(DaroObjCAdInfo *)adInfo {
        NSLog(@"[DARO] Rewarded ad shown");
    }

    - (void)rewardedAdDidFail:(DaroObjCRewardedAd *)ad
                       toShow:(DaroObjCAdInfo *)adInfo
                        error:(NSError *)error {
        NSLog(@"[DARO] Failed to show: %@", error.localizedDescription);
    }

    - (void)rewardedAdDidClick:(DaroObjCRewardedAd *)ad
                        adInfo:(DaroObjCAdInfo *)adInfo {
        NSLog(@"[DARO] Rewarded ad clicked");
    }

    - (void)rewardedAdDidRecordImpression:(DaroObjCRewardedAd *)ad
                                   adInfo:(DaroObjCAdInfo *)adInfo {
        NSLog(@"[DARO] Impression recorded");
    }

    - (void)rewardedAdDidEarnReward:(DaroObjCRewardedAd *)ad
                             adInfo:(DaroObjCAdInfo *)adInfo
                       rewardedItem:(DaroObjCRewardedItem *)rewardedItem {
        NSLog(@"[DARO] Reward earned! Type: %@, Amount: %d",
              rewardedItem.rewardType, rewardedItem.amount);
    }

    - (void)rewardedAdDidDismiss:(DaroObjCRewardedAd *)ad
                          adInfo:(DaroObjCAdInfo *)adInfo {
        NSLog(@"[DARO] Rewarded ad dismissed");
    }
    ```

    **4. 광고 표시:**

    ```objc theme={null}
    - (void)showRewardedAd {
        if (self.rewardedAd.isReady) {
            [self.rewardedAd showFrom:self];
        } else {
            NSLog(@"[DARO] Ad is not ready to show");
        }
    }
    ```
  </Tab>
</Tabs>

## 리워드 아이템 구조

리워드 비디오 광고 시청 완료 시 전달되는 리워드 아이템은 다음과 같은 구조를 가집니다:

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    struct DaroRewardedItem {
        let amount: Int           // 보상 수량
        let rewardType: String    // 보상 타입 (예: "coin", "gem", "energy" 등)
    }
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objc theme={null}
    @interface DaroObjCRewardedItem : NSObject

    @property (nonatomic, assign, readonly) NSInteger amount;      // 보상 수량
    @property (nonatomic, strong, readonly) NSString *rewardType;  // 보상 타입 (예: "coin", "gem", "energy" 등)

    @end
    ```
  </Tab>
</Tabs>

## 추가 기능

### 사용자 식별자 설정

다음 코드는 사용자의 내부 User ID를 태그하는 방법을 보여줍니다. User ID 문자열의 최대 크기는 8192자입니다.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    DaroAds.shared.userId = "user_id"
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objc theme={null}
    [DaroObjCAds shared].userId = @"user_id";
    ```
  </Tab>
</Tabs>

### 플레이스먼트 설정

광고 표시 전에 placement를 설정할 수 있습니다.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    daroRewardedAd?.setPlacement("your_rewarded_placement")
    daroRewardedAd?.show(viewController: self)
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objc theme={null}
    [self.rewardedAd setPlacement:@"your_rewarded_placement"];
    [self.rewardedAd showFrom:self];
    ```
  </Tab>
</Tabs>

### 커스텀 데이터 설정

리워드 비디오 광고에 커스텀 데이터를 추가할 수 있습니다. 이 데이터는 서버 측 콜백에서 사용할 수 있습니다.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    daroRewardedAd?.setCustomData("your_custom_data")
    daroRewardedAd?.show(viewController: self)
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objc theme={null}
    [self.rewardedAd setCustomData:@"your_custom_data"];
    [self.rewardedAd showFrom:self];
    ```
  </Tab>
</Tabs>

***

## 트러블슈팅: 광고 닫기 버튼 겹침 이슈

<Warning>
  DARO iOS SDK를 사용해 보상형 광고를 표시할 때, 일부 광고 크리에이티브에서 상단 Safe Area 또는 Status Bar 영역과 UI가 겹쳐 보이는 현상이 발생할 수 있습니다.
  아래는 광고가 표시되는 동안만 Status Bar를 숨기고, 광고 종료 시 원복하는 방법을 안내합니다.
</Warning>

<Tabs>
  <Tab title="Swift">
    **1. ViewController에 Status Bar 제어 프로퍼티 추가:**

    ```swift theme={null}
    class ExampleViewController: UIViewController {
        private var isAdShowing = false

        override var prefersStatusBarHidden: Bool {
            return isAdShowing
        }

        override var childForStatusBarHidden: UIViewController? {
            return presentedViewController
        }
    }
    ```

    **2. 광고 표시 전 Status Bar 숨기기 및 콜백에서 복구:**

    ```swift theme={null}
    private func showAd(ad: DaroRewardedAd) {
        self.daroRewardedAd = ad

        self.daroRewardedAd?.rewardedAdListener.onEarnedReward = { adInfo, rewardedItem in
            print("[DARO] Reward Ad earned: \(adInfo) \(rewardedItem)")
        }

        self.daroRewardedAd?.rewardedAdListener.onShown = { [weak self] adInfo in
            print("[DARO] Reward Ad shown")
        }

        self.daroRewardedAd?.rewardedAdListener.onDismiss = { [weak self] adInfo in
            self?.isAdShowing = false
            self?.setNeedsStatusBarAppearanceUpdate()
        }

        self.daroRewardedAd?.rewardedAdListener.onFailedToShow = { [weak self] adInfo, error in
            self?.isAdShowing = false
            self?.setNeedsStatusBarAppearanceUpdate()
        }

        // show() 직전에 Status Bar 숨기기
        isAdShowing = true
        setNeedsStatusBarAppearanceUpdate()
        daroRewardedAd?.show(viewController: self)
    }
    ```
  </Tab>

  <Tab title="Objective-C">
    **1. 헤더 파일에 프로퍼티 추가:**

    ```objc theme={null}
    @interface ExampleViewController ()
    @property (nonatomic, assign) BOOL adShowing;
    @end
    ```

    **2. Status Bar 제어 메서드 오버라이드:**

    ```objc theme={null}
    - (BOOL)prefersStatusBarHidden {
        return self.adShowing;
    }

    - (UIViewController *)childViewControllerForStatusBarHidden {
        return self.presentedViewController;
    }
    ```

    **3. 광고 표시 전 숨기기 및 콜백에서 복구:**

    ```objc theme={null}
    - (void)showRewardedAd {
        // show() 직전에 Status Bar 숨기기
        self.adShowing = YES;
        [self setNeedsStatusBarAppearanceUpdate];

        [self.rewardedAd showFrom:self];
    }

    // 광고 닫힘 시 복구
    - (void)rewardedAdDidDismiss:(DaroObjCRewardedAd *)ad
                          adInfo:(DaroObjCAdInfo *)adInfo {
        self.adShowing = NO;
        [self setNeedsStatusBarAppearanceUpdate];
    }

    // 광고 표시 실패 시 복구
    - (void)rewardedAdDidFail:(DaroObjCRewardedAd *)ad
                       toShow:(DaroObjCAdInfo *)adInfo
                        error:(NSError *)error {
        self.adShowing = NO;
        [self setNeedsStatusBarAppearanceUpdate];
    }
    ```
  </Tab>
</Tabs>
