# iOS용 보상형 광고 통합

> 광고 유닛을 초기화하고, 델리게이트 설정하고, 광고 이벤트를 처리하여 iOS 앱에 보상형 비디오 광고 유닛을 구현합니다.

Unity 레벨플레이 보상형 광고 전체 화면 광고 유닛으로, 일반적으로 앱 라이프사이클 동안 자연스럽게 전환 시점에 게재됩니다. 

> **Note:**
>
> 이 기술 자료는 SDK 8.5.0 이상에 해당합니다.

## 필수 조건##prerequisites

* 레벨플레이 SDK를 애플리케이션 올바르게 연동했는지 확인합니다. 통합은 [여기](/grow/levelplay/sdk/ios/sdk-integration.md) 설명되어 있습니다.
* 레벨플레이 초기화 API 사용하여 SDK를 초기화해야 합니다.
* 레벨플레이 대시보드에서 AdUnitID를 찾습니다.

## 보상형 광고 오브젝트 생성##create-rewarded-ad-object

보상형 광고 오브젝트의 생성은 **onInitSuccess** 콜백을 수신한 후에 수행해야 합니다.

오브젝트 세션 전체에 걸쳐 여러 로드와 표시를 처리할 수 있는 재사용 가능한 인스턴스. 생성 후에는 동일한 광고 유닛의 광고를 로드하고 표시하는 데 사용해야 합니다.

더 고급 구현을 위해 필요한 경우 여러 보상형 광고 객체를 생성할 수 있습니다.

1. **Objective-C**

   ```objective-c
   self.rewardedAd = [[LPMRewardedAd alloc] initWithAdUnitId:@"adUnitId"];	 
   ```

2. **Swift**

   ```swift
   self.rewardedAd = LPMRewardedAd(adUnitId: "adUnitId")
   ```

## 델리게이트 구현##implement-delegates

코드에 **LPMRewardedAdDelegate를 구현**하여 광고 전송에 대해 알 수 있습니다. 

* 보상형 광고 광고를 로드하기 전에 델리게이트를 설정하는 것이 좋습니다.
* 각 보상형 광고 광고에는 자체 델리게이트 구현이 있어야 합니다.
* 델리게이트 메서드는 메인 스레드 실행됩니다.

1. **Objective-C**

   ```objective-c
   self.rewardedAd = [[LPMRewardedAd alloc] initWithAdUnitId:@"adUnitId"]; 
   self.rewardedAd.delegate = self;

   #pragma mark - LPMRewardedAdDelegate Methods
   - (void)didLoadAdWithAdInfo:(LPMAdInfo *)adInfo {}
   - (void)didFailToLoadAdWithAdUnitId:(NSString *)adUnitId error:(NSError *)error {}
   - (void)didChangeAdInfo:(LPMAdInfo *)adInfo {}
   - (void)didDisplayAdWithAdInfo:(LPMAdInfo *)adInfo {}
   - (void)didFailToDisplayAdWithAdInfo:(LPMAdInfo *)adInfo 오류:(NSError *)오류 {}
   - (void)didClickAdWithAdInfo:(LPMAdInfo *)adInfo {}
   - (void)didCloseAdWithAdInfo:(LPMAdInfo *)adInfo {}
   - (void)didRewardAdWithAdInfo:(LPMAdInfo *)adInfo reward:(LPMReward *)reward {}
   ```

2. **Swift**

   ```swift
   self.rewardedAd = LPMRewardedAd(adUnitId: "adUnitId") 
   self.rewardedAd.setDelegate(self)

   // MARK: LPMRewardedAdDelegate methods
   func didLoadAd(with adInfo: LPMAdInfo) {}
   func didFailToLoadAd(withAdUnitId adUnitId: 문자열, 오류: 오류) {}
   func didChangeAdInfo(_ adInfo: LPMAdInfo) {}
   func didDisplayAd(with adInfo: LPMAdInfo) {}
   func didFailToDisplayAd(with adInfo: LPMAdInfo, 오류: 오류) {}
   func didClickAd(with adInfo: LPMAdInfo) {}
   func didCloseAd(with adInfo: LPMAdInfo) {}
   func didRewardAd(with adInfo: LPMAdInfo, reward: LPMReward) {}
   ```

### 레벨플레이 광고 정보##levelplay-ad-info

**LPMAdInfo** 파라미터에는 로드된 광고에 대한 정보가 포함되어 있습니다.
자세히 알아보기 LPMAdInfo 구현 및 사용 가능한 필드 [여기](/grow/levelplay/sdk/ios/levelplay-listener-adinfo-integration.md).

## 보상형 광고 세부 정보 가져오기##get-rewarded-ad-details

getReward API 사용하여 레벨플레이 대시보드에서 설정한 보상 데이터에 액세스, 접근. 다른 Mediation API와 달리 이 호출은 초기화 후 SDK에 로컬에 저장된 데이터를 반환하는 독립성 호출. 이렇게 하면 광고를 시작하기 전에 사용자에게 잠재적인 보상을 알리는 동적 데이터 기반 UI를 빌드 수 있으므로 앱에서 보상 값을 하드코딩할 필요가 없습니다.

### 필수 조건##prerequisites

getReward API 구현하기 전에 프로젝트가 다음 기술 요구 사항을 충족하는지 확인합니다.

* **SDK Initialization**: initSDK를 호출 onInitializationSuccess 콜백 기다려 보상 데이터가 캐싱되었는지 확인합니다.
* **광고 오브젝트 인스턴스**: API 호출하기 전에 유효한 광고 유닛 ID로 보상형 광고 광고 오브젝트 인스턴스화.
* **Minimum SDK Version**: 레벨플레이 SDK 버전 8.1.0 이상(네이티브 또는 Unity 패키지)을 사용합니다.

### 베스트 프랙티스##best-practices

안정적이고 예측 가능한 통합을 보장하려면 다음 권장 사항을 따르십시오.

* 초기화 성공 시 **호출**: getReward를 호출 가장 적합한 시점은 초기화 성공 리스너 내부입니다. 이렇게 하면 사용자 화면에 진입할 때마다 UI가 준비됩니다.
* **빈 상태 확인**: UI를 업데이트하기 전에 항상 이 양을 0 이상으로 확인해야 합니다. 이렇게 하면 초기화 중에 네트워크 오류가 발생하는 경우 원활한 사용자 경험 보장할 수 있습니다.
* **플레이스먼트 정밀도**: getReward("placementName")에 사용된 문자열이 레벨플레이 대시보드에 정의된 이름과 정확히 일치하는지 확인합니다.

### API 구조, 구조체##api-structure

getReward 메서드를 사용하면 레벨플레이 대시보드에서 동기화된 보상 데이터에 액세스, 접근 수 있습니다. 이 메서드를 사용하여 로컬 SDK 캐시 특정 플레이스먼트 값 또는 전역 광고 유닛 기본값을 쿼리 수 있습니다.

#### getReward##getreward

```objective-c
- (LPMReward *)getRewardWithPlacementName:(NSString *)placementName;
```

특정 플레이스먼트 또는 기본 광고 유닛의 보상 이름과 금액을 가져옵니다. 사용할 다른 파라미터는 없습니다.

| 파라미터          | 설명                                                           |
| ------------- | ------------------------------------------------------------ |
| placementName | 레벨플레이 대시보드에 정의된 플레이스먼트의 고유 식별자. 광고 유닛의 기본 보상을 가져오는 `nil` 전달. |

이름(String)과 양(int)을 포함하는 LPMReward 오브젝트 반환합니다.

### 초안 수립##initial-setup

getReward API 레벨플레이 SDK의 핵심 컴포넌트 기능하며 다음 로직에 따라 동작하여 데이터를 지연 없이 사용할 수 있습니다.

* **통합 기능**: 보상 데이터는 초기 SDK 설정 중에 가져오기 때문에 API 호출 순간적이며 네트워크 요청이 필요하지 않습니다.
* **에디터 설정**: 앱이 레벨플레이 SDK와 연동되면 API 즉시 사용할 수 있습니다. 이 기능을 테스트하려면 추가 에셋이나 플러그인이 필요하지 않습니다.

### 보상 선택 로직 이해##understand-reward-selection-logic

API 특정 계층 구조 구조에 따라 LPMReward 오브젝트 반환합니다. 이 로직을 이해하면 특정 보상이 표시되는 이유를 문제 해결 데 도움이 됩니다.

* **플레이스먼트 레벨**: 호출 유효한 플레이스먼트 이름이 제공되면 SDK는 대시보드에서 해당 플레이스먼트에 대해 설정된 특정 보상을 반환합니다.
* **광고 유닛 레벨**: 플레이스먼트 이름이 null이거나 찾을 수 없으면 SDK는 광고 유닛에 정의된 기본 보상으로 폴백합니다.
* **폴백 상태**: 초기화가 완료되기 전에 API 호출되면 빈 문자열 이름과 금액이 0인 보상 오브젝트 반환합니다.

### UI 동적 업데이트##update-your-ui-dynamically

getReward API를 사용하여 정적 버튼을 고도의 행동 호출로 변환합니다(동사), 트랜스폼(명사). 예를 들어 일반 "Watch Video" 버튼 대신 "Watch to earn 50 Gold"를 표시할 수 있습니다.

* **확인 금액**: UI 컴포넌트를 업데이트하기 전에 항상 reward.amount > 0을 확인해야 합니다.
* **이벤트 기반 업데이트**: 초기화 성공 리스너 내에서 API 호출 사용자 화면에 진입할 때 UI가 정확한지 확인합니다.
* **대소문자 구분**: 코드의 플레이스먼트 이름 문자열이 레벨플레이 대시보드와 정확히 일치하는지 확인합니다. 일치하지 않는 문자열은 광고 유닛 폴백 트리거합니다.

### 보상 데이터 검색 예시##retrieve-reward-data-examples

다음 예제는 iOS용 보상 API 호출 방법을 보여 줍니다.

1. **Objective-C**

   ```objective-c
   /** 
    * 광고와 관련된 보상을 가져옵니다. 
    * 이 메서드를 사용하여 광고 유닛 또는 플레이스먼트에 설정된 보상을 가져옵니다. The 
    * 유효한 플레이스먼트 이름이 있는 경우 플레이스먼트별 보상이 광고 유닛 보상보다 우선합니다. 
    * 제공됩니다. 
    * @param placement 보상을 가져오거나 `nil` 광고 유닛의 보상을 사용하기 위한 플레이스먼트 이름입니다. 
    * @return A `LPMReward` 오브젝트 실패 시 빈 보상을 반환합니다(`name: ""` 및 `amount: 0`). 
    */ 
   LPMReward *reward = [self.rewardedAd getRewardWithPlacementName:@"main_menu"];
   NSLog(@"Reward: %ld %@", (long)reward.amount, reward.name);
   ```

2. **Swift**

   ```swift
   /** 
    * 광고와 관련된 보상을 가져옵니다. 
    * 이 메서드를 사용하여 광고 유닛 또는 플레이스먼트에 설정된 보상을 가져옵니다. The 
    * 유효한 플레이스먼트 이름이 있는 경우 플레이스먼트별 보상이 광고 유닛 보상보다 우선합니다. 
    * 제공됩니다. 
    * @param placementName 보상을 가져오거나 `nil` 광고 유닛의 보상을 사용하기 위한 플레이스먼트 이름입니다. 
    * @return A `LPMReward` 오브젝트 실패 시 빈 보상을 반환합니다(`name: ""` 및 `amount: 0`). 
    */ 
   let reward = self.rewardedAd.getReward(placementName: "main_menu")
   print(" \\(reward.amount) \\(reward.name)을 얻으려면 기다리십시오")
   ```

### getReward API 구현 문제 해결##troubleshooting-getreward-api-implementation

* **보상 금액은 0을 반환**합니다. 이는 일반적으로 onInitializationSuccess 콜백 전에 API 호출된 경우에 발생합니다. 보상을 쿼리하기 전에 SDK가 완전히 준비되었는지 확인합니다.
* **잘못된 보상 유형 표시**: 여러 플레이스먼트가 있는지 확인합니다. 플레이스먼트 이름의 철자가 잘못되면 SDK는 특정 플레이스먼트 보상 대신 기본 광고 유닛 보상으로 설정됩니다.

## 보상형 광고 로드##load-rewarded-ad

보상형 광고를 로드하려면 **loadAd를** 사용합니다.

1. **Objective-C**

   ```objective-c
   [self.rewardedAd loadAd];
   ```

2. **Swift**

   ```swift
   self.rewardedAd.loadAd()	 
   ```

## 보상형 광고 표시##show-rewarded-ad

**didLoadAd** 콜백을 수신한 후 보상형 광고를 표시합니다.

* **ViewController를** 공유해야 합니다. 
* 플레이스먼트를 사용하는 경우 아래의 플레이스먼트 섹션에 표시된 대로 **showAd** API에서 플레이스먼트 이름을 전달합니다.
* 광고가 사용자 성공적으로 표시되면 로딩 단계를 반복하여 다른 광고를 로드할 수 있습니다. 

1. **Objective-C**

   ```objective-c
   - (void)showRewardedAd {
       // 광고가 준비되었는지 확인합니다.
       if ([self.rewardedAd isAdReady]) {
           // 플레이스먼트 없이 표시
           [self.rewardedAd showAdWithViewController:self placementName:NULL];
       }
   }	 
   ```

2. **Swift**

   ```swift
   func showRewardedAd() {
       // 광고가 준비되었는지 확인합니다.  
       if self.rewardedAd.isAdReady() {
           // 플레이스먼트 없이 표시
           self.rewardedAd.showAd(viewController: self, placementName: nil)
       }
   }	 
   ```

### 광고가 준비되었는지 확인##check-ad-is-ready

표시 실패를 방지하고 광고가 올바르게 표시되었는지 확인하기 위해 **showAd** API를 호출하기 전에 다음 API를 사용하는 것이 좋습니다.

**isAdReady** – 광고가 성공적으로 로드되고 광고 유닛이 제한되지 않거나 거짓이 아닌 경우 true를 반환합니다.

**isPlacementCapped** – 유효한 플레이스먼트가 제한되면 true를 반환합니다. 플레이스먼트가 유효하지 않거나 제한이 없는 경우 이 API false를 반환합니다.

1. **Objective-C**

   ```objective-c
   // 광고가 준비되었는지, 플레이스먼트가 제한되지 않았는지 확인합니다. 
   if ([self.rewardedAd isAdReady] &amp;&amp; ![LPMRewardedAd isPlacementCapped:placementName]) {
       [self.rewardedAd showAdWithViewController:self placementName:placementName];
   }
   ```

2. **Swift**

   ```swift
   // 광고가 준비되었는지, 플레이스먼트가 제한되지 않았는지 확인합니다. 
   if self.rewardedAd.isAdReady(), !LPMRewardedAd.isPlacementCapped(placementName) {
       self.rewardedAd.showAd(viewController: self, placementName: placementName)
   }	 
   ```

### Placements##placements

레벨플레이 대시보드에서 보상형 광고의 [플레이스먼트](/grow/levelplay/platform/settings/placements.md) 속도와 한도를 지원합니다. 

보상형 광고에 대한 플레이스먼트가 설정된 경우, 특정 플레이스먼트에 광고를 게재하려면 **showAd** 메서드를 호출합니다.

1. **Objective-C**

   ```objectivec
   // 광고가 준비되었는지, 플레이스먼트가 제한되지 않았는지 확인합니다.
   if ([self.rewardedAd isAdReady] &amp;&amp; ![LPMRewardedAd isPlacementCapped:placementName]) {
       // 플레이스먼트가 있는 광고 표시
       [self.rewardedAd showAdWithViewController:self placementName:@"PlacementName"];
   }	 
   ```

2. **Swift**

   ```swift
   // 광고가 준비되었는지, 플레이스먼트가 제한되지 않았는지 확인합니다. 
   if self.rewardedAd.isAdReady(), !LPMRewardedAd.isPlacementCapped(placementName) {
       // 플레이스먼트가 있는 광고 표시
       self.rewardedAd.showAd(viewController: self, placementName: placementName) 
   }	 
   ```

### 동적 UserId##dynamic-userid

동적 사용자 ID는 세션 전반에서 변경할 수 있는 AdRewarded 거래를 확인하는 데 사용되는 파라미터. 이 파라미터는 [서버 간](/grow/levelplay/platform/settings/server-to-server-callback.md) 광고 보상형 광고 콜백을 통해 수신되며 showAd를 호출하기 전에 설정해야 합니다.

* 문자열 값은 영숫자 1\~64자로 구성되어야 합니다.
* 보상 세부 정보가 포함된 콜백 URL에 `dynamicUserId` 파라미터가 표시됩니다.

1. **Objective-C**

   ```objective-c
   [LevelPlay setDynamicUserId:@"userId"];
   ```

2. **Swift**

   ```swift
   LevelPlay.setDynamicUserId("userId")
   ```

## 보상형 광고 광고의 전체 구현 예시##full-implementation-example-of-rewarded-ads

1. **Objective-C**

   ```objective-c
   NS_ASSUME_NONNULL_BEGIN
   @interface RewardedAdViewController () <LPMRewardedAdDelegate>
   @properties(nonatomic, strong) LPMRewardedAd *rewardedAd;
   @end
   @implementation RewardedAdViewController
   - (void)createRewardedAd {
       self.rewardedAd = [[LPMRewardedAd alloc] initWithAdUnitId:@"adUnitId"];
       self.rewardedAd.delegate = self;
   }
   - (void)loadRewardedAd {
       // 광고를 로드하거나 다시 로드하는 데 사용
       [self.rewardedAd loadAd];
   }
   - (void)showRewardedAd {
       if ([self.rewardedAd isAdReady]) {
       [self.rewardedAd showAdWithViewController:self placementName:NULL];
     }
   }
   - (void)showRewardedAdWithPlacementName:(NSString *)placementName {
       // 광고가 준비되었는지, 플레이스먼트가 제한되지 않았는지 확인합니다. 
       if ([self.rewardedAd isAdReady] &amp;&amp; ![LPMRewardedAd isPlacementCapped:placementName]) {
           [self.rewardedAd showAdWithViewController:self placementName:placementName];
       }
   }
   #pragma 마크 - LPMRewardedAdDelegate 메서드
   - (void)didLoadAdWithAdInfo:(LPMAdInfo *)adInfo {}
   - (void)didFailToLoadAdWithAdUnitId:(NSString *)adUnitId error:(NSError *)error {}
   - (void)didChangeAdInfo:(LPMAdInfo *)adInfo {}
   - (void)didDisplayAdWithAdInfo:(LPMAdInfo *)adInfo {}
   - (void)didFailToDisplayAdWithAdInfo:(LPMAdInfo *)adInfo 오류:(NSError *)오류 {}
   - (void)didClickAdWithAdInfo:(LPMAdInfo *)adInfo {}
   - (void)didCloseAdWithAdInfo:(LPMAdInfo *)adInfo {}
   - (void)didRewardAdWithAdInfo:(LPMAdInfo *)adInfo reward:(LPMReward *)reward {} 
   @end
   NS_ASSUME_NONNULL_END
   ```

2. **Swift**

   ```swift
   클래스 RewardedAdViewController: UIViewController, LPMRewardedAdDelegate {
   var rewardedAd: LPMRewardedAd!

   func createRewardedAd() {
       self.rewardedAd = LPMRewardedAd(adUnitId: "adUnitId")
       self.rewardedAd.setDelegate(self)
   }

   func loadRewardedAd() {
       // used to load or reload the ad
       self.rewardedAd.loadAd()
   }

   func showRewardedAd() {
       if self.rewardedAd.isAdReady() {
           self.rewardedAd.showAd(viewController: self, placementName: nil)
       }
   }

   func showRewardedAd(withPlacementName placementName): 문자열) {
       // check that ad is ready and that the placement is not capped 
       if self.rewardedAd.isAdReady(), !LPMRewardedAd.isPlacementCapped(placementName) {
           self.rewardedAd.showAd(viewController: self, placementName: placementName)
       }
   }

   // MARK: LPMRewardedAdDelegate 메서드
   func didLoadAd(with adInfo: LPMAdInfo) {}
   func didFailToLoadAd(withAdUnitId adUnitId: 문자열, 오류: 오류) {}
   func didChangeAdInfo(_ adInfo: LPMAdInfo) {}
   func didDisplayAd(with adInfo: LPMAdInfo) {}
   func didFailToDisplayAd(with adInfo: LPMAdInfo, 오류: 오류) {}
   func didClickAd(with adInfo: LPMAdInfo) {}
   func didCloseAd(with adInfo: LPMAdInfo) {}
   func didRewardAd(with adInfo: LPMAdInfo, reward: LPMReward) {} 
   }
   ```

## 레벨플레이 Mediation 데모 앱##levelplay-mediation-demo-app

Integration Demo 애플리케이션 앱에 보상형 광고 광고 유닛 API를 연동하는 방법을 보여 줍니다.

[iOS 데모 애플리케이션 다운로드](https://github.com/ironsource-mobile/Mediation-Demo-Apps)

[통합 테스트 제품군](/grow/levelplay/sdk/ios/integration-test-suite.md)과의 통합 여부 확인

## 다음 단계##next-steps

추가 보상형 광고 광고 네트워크를 연동하거나 추가 광고 형식을 설정 Unity 통합 가이드를 따르십시오.

* [Mediation Networks 추가](/grow/levelplay/sdk/ios/mediation-networks.md)
* [인터스티셜 광고](/grow/levelplay/sdk/ios/interstitial-integration.md)
* [배너 광고](/grow/levelplay/sdk/ios/banner-integration.md)
* [네이티브 광고](/grow/levelplay/sdk/ios/native-ads-integration.md)
