# Flutter의 보상형 광고 통합

> 광고 배치, 제한, 속도, 매뉴얼 로딩 옵션을 활용하여 플러터 애플리케이션 보상형 비디오 광고를 통합하여 사용자 참여를 최적화할 수 있습니다.

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

## 필수 조건##prerequisites

* 앱에 Flutter 플러그인을 [통합](/grow/levelplay/sdk/flutter/plugin-integration.md)해야 합니다.
* 레벨플레이 초기화 API 사용하여 SDK를 초기화해야 합니다.
* 레벨플레이 대시보드에서 AdUnitID를 찾습니다.

## 보상형 광고 생성 및 이벤트 등록##create-rewarded-and-register-to-events

`onInitSuccess` 콜백을 수신한 후 레벨플레이 플랫폼(레벨플레이 SDK 단계 초기화)에 정의된 대로 관련 광고 유닛 ID를 사용하여 광고 유닛을 생성할 수 있습니다.

생성된 보상형 광고 광고 유닛의 보상형 광고 리스너를 설정하여 광고 게재를 알립니다.

```dart
final LevelPlayRewardedAd _rewardedAd = LevelPlayRewardedAd(adUnitId: [YOUR_AD_UNIT_ID]);
@override
void initState() {
    super.initState();
    _rewardedAd.setListener(this);
}
// LevelPlayRewardedAdListener methods
@override
void onAdLoaded(LevelPlayAdInfo adInfo) {}
@override
void onAdLoadFailed(LevelPlayAdError error) {} 
@override
void onAdDisplayed(LevelPlayAdInfo adInfo) {}
@override
void onAdDisplayFailed(LevelPlayAdError error,
 LevelPlayAdInfo adInfo) {}
@override 
void onAdClosed(LevelPlayAdInfo adInfo) {}
@override
void onAdClicked(LevelPlayAdInfo adInfo) {} 
@override
void onAdInfoChanged(LevelPlayAdInfo adInfo) {}
@override
void onAdRewarded(LevelPlayReward reward, LevelPlayAdInfo adInfo) {}
```

### 레벨플레이 보상형 광고 광고 콜백##levelplay-rewarded-ad-callbacks

* `onAdLoaded`: 광고가 성공적으로 로드되면 제공됨
* `onAdLoadFailed`: 광고 로드 실패 시 제공됩니다. 광고 유닛 정보가 포함됩니다.
* `onAdDisplayed`: 광고가 표시될 때 제공됩니다. 이는 노출과 동일합니다.
* `onAdDisplayFailed`(선택 사항): 광고 표시 실패 시 제공됨
* `onAdRewarded`: 광고 보상형 광고 제공될 때 제공됩니다. 광고 유닛 정보와 보상 정보가 포함됩니다.
* `onAdClicked`(선택 사항): 사용자 광고를 클릭할 때 제공됨
* `onAdClosed`: 광고가 닫힐 때 제공됨
* `onAdInfoChanged`(선택 사항): 광고 정보가 업데이트될 때 제공됩니다. 다른 광고가 로드되었을 때 사용 가능하며 더 높은 CPM/Rate를 포함합니다.

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

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

### 필수 조건##prerequisites

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

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

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

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

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

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

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

#### getReward##getreward

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

* `placementName`: 레벨플레이 대시보드에 정의된 플레이스먼트의 고유 식별자. 광고 유닛의 기본 보상을 가져오는 `null` 전달.

이름(String)과 금액(int)이 포함된 LevelPlayReward 오브젝트 반환합니다.

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

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

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

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

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

* 플레이스먼트 레벨: 호출 유효한 플레이스먼트 이름이 제공되면 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가 정확한지 확인합니다.
* 대소문자 구분: 코드의 플레이스먼트 이름 문자열이 레벨플레이 대시보드와 정확히 일치하는지 확인합니다. 일치하지 않는 문자열은 광고 유닛 폴백 트리거합니다.

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

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

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

**onInitSuccess** 콜백을 수신하면 보상형 광고를 로드할 수 있습니다. 이는 메서드를 사용하여 수행해야 합니다.

```dart
_rewardedAd.loadAd();
```

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

showAd API를 사용하여 **onAdLoaded** 콜백을 수신한 후 보상형 광고를 표시할 수 있습니다.

[플레이스먼트를](/grow/levelplay/platform/settings/placements.md) 사용하는 경우 아래와 같이 API의 일부로 이름을 공유합니다.

```dart
// Show ad without placement
_rewardedAd.showAd();
// Show ad with placement
_rewardedAd.showAd(placement: [YOUR_PLACEMENT]);
```

## 광고 확인 준비##check-ad-ready

showFailure를 방지하고 광고를 올바르게 표시할 수 있도록 showAd() API 호출하기 전에 다음 API 사용하는 것이 좋습니다.

* `isAdReady`: 광고가 성공적으로 로드되고 광고 유닛이 제한되지 않으면 true를, 그렇지 않으면 false를 반환합니다.
* `isPlacementCapped`: 유효한 플레이스먼트가 제한되면 true를 반환합니다. 플레이스먼트가 유효하지 않거나 제한되지 않으면 이 API false를 반환합니다.

```dart
// Check that ad is ready and that the placement is not capped 
if(_rewardedAd.isAdReady() && !LevelPlayRewardedAd.isPlacementCapped([YOUR_PLACEMENT])) {
     _rewardedAd.showAd(placement:[YOUR_PLACEMENT]);
}
```

광고가 플레이어 성공적으로 표시되면 Load 보상형 광고 Ad 단계를 반복하여 다른 광고를 로드할 수 있습니다. 한 번에 하나의 광고를 로드할 때 새 광고 엔티티 생성할 필요가 없습니다.

### 동적 UserId##dynamic-userid

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

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

```dart
LevelPlay.setDynamicUserId("userId");
```

## 사용자 보상##reward-the-user

레벨플레이 SDK는 사용자가 동영상을 성공적으로 완료할 때마다 `onAdRewarded`를 작동시킵니다.

`onAdRewarded`와 `onAdClosed`은 비동기입니다. `onAdClosed` 후에 `onAdRewarded`가 해고되는 경우에도 보상을 부여하도록 청취기를 설정해야 합니다.

```dart
@override
void onAdRewarded(LevelPlayReward reward, LevelPlayAdInfo adInfo) {
    // Implement logic to grant the reward to the user
}
```

## 여러 광고 유닛 보상형 광고 API##multiple-ad-unit-rewarded-apis

| 카테고리 | 레거시                              | 광고 단위 이름(새로운)         |
| ---- | -------------------------------- | --------------------- |
| 클래스  | `IronSource`                     | `LevelPlayRewardedAd` |
| API  | `loadRewardedVideo`              | `loadAd`              |
| API  | `showRewardedVideo`              | `showAd`              |
| API  | `isRewardedVideoPlacementCapped` | `isPlacementCapped`   |
| API  | `isRewardedVideoAvailable`       | `isAdReady`           |
| API  | `placement.getRewardName`        | `reward.name`         |
| API  | `placement.getRewardAmount`      | `reward.amount`       |

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

```dart
final LevelPlayRewardedAd _rewardedAd = LevelPlayRewardedAd(adUnitId: 'YOUR_AD_UNIT_ID');
@override
void initState() {
    super.initState();
    _rewardedAd.setListener(this);
    _rewardedAd.loadAd();
}
@override
void onAdRewarded(LevelPlayReward reward, LevelPlayAdInfo adInfo) {
    // Implement your logic here...
}
@override
void onAdClicked(LevelPlayAdInfo adInfo) {
    // Implement your logic here...
}
@override
void onAdClosed(LevelPlayAdInfo adInfo) {
    // Implement your logic here...
}
@override
void onAdDisplayFailed(LevelPlayAdError error, LevelPlayAdInfo adInfo) {
    // Implement your logic here...
}
@override
void onAdDisplayed(LevelPlayAdInfo adInfo) {
    // Implement your logic here...
}
@override
void onAdInfoChanged(LevelPlayAdInfo adInfo) {
    // Implement your logic here...
}
@override
void onAdLoadFailed(LevelPlayAdError error) {
    // Implement your logic here...
}
@override
void onAdLoaded(LevelPlayAdInfo adInfo) {
    // Implement your logic here, for example showing the ad
    _rewardedAd.showAd();
}
// Rest of the widget
// End of widget...
```
