概要
リワード広告は、ユーザーが動画広告を最後まで視聴すると、ゲーム内通貨、ライフ、ヒントなどの報酬を提供するフルスクリーン動画広告です。主な特徴
- フルスクリーンで表示される動画広告
- ユーザーが広告を完全に視聴した場合にのみ報酬を提供
- ユーザーが自ら広告視聴を選択 (例: 「動画を見てライフを獲得」ボタン)
- 報酬タイプと数量を設定可能
開発環境ではテストユニットIDを使用してください:
PUBLIC_TEST_UNIT_ID_REWARDED実装方法
リワード広告は次の手順で実装します:- AdropRewardedAdインスタンスの生成 - ユニットIDで広告オブジェクトを生成
- デリゲートの設定 - 広告イベント処理のためのdelegateを指定
- 広告の読み込み -
load()メソッドで広告をリクエスト - 広告の表示 -
show()メソッドで広告を表示し、報酬を処理
Swift例
基本実装
import UIKit
import AdropAds
class RewardedViewController: UIViewController {
private var rewardedAd: AdropRewardedAd?
override func viewDidLoad() {
super.viewDidLoad()
// 1. AdropRewardedAdインスタンスの生成
rewardedAd = AdropRewardedAd(unitId: "YOUR_UNIT_ID")
// 2. デリゲートの設定
rewardedAd?.delegate = self
// 3. 広告の読み込み
rewardedAd?.load()
}
@IBAction func showRewardedAdButtonTapped(_ sender: UIButton) {
// 広告が読み込まれたか確認
guard rewardedAd?.isLoaded == true else {
print("広告がまだ読み込まれていません")
return
}
// 4. 広告の表示と報酬処理
rewardedAd?.show(fromRootViewController: self) { [weak self] type, amount in
// 報酬付与処理
print("報酬獲得 - タイプ: \(type), 数量: \(amount)")
self?.grantReward(type: type, amount: amount)
}
}
private func grantReward(type: Int, amount: Int) {
// ユーザーに報酬を付与
// 例: ゲーム通貨の追加、ライフの回復など
// ⚠️ 重要: サーバーで報酬を検証することを推奨
// クライアントのみで報酬を処理すると不正行為が可能
}
}
// MARK: - AdropRewardedAdDelegate
extension RewardedViewController: AdropRewardedAdDelegate {
// 必須: 広告受信成功
func onAdReceived(_ ad: AdropRewardedAd) {
print("広告受信完了")
// 広告視聴ボタンを有効化するなど
}
// 必須: 広告受信失敗
func onAdFailedToReceive(_ ad: AdropRewardedAd, _ errorCode: AdropErrorCode) {
print("広告受信失敗: \(errorCode)")
// 広告視聴ボタンを無効状態に維持するなど
}
// オプション: 広告表示
func onAdImpression(_ ad: AdropRewardedAd) {
print("広告表示")
}
// オプション: 広告クリック
func onAdClicked(_ ad: AdropRewardedAd) {
print("広告クリック")
}
// オプション: フルスクリーン広告表示直前
func onAdWillPresentFullScreen(_ ad: AdropRewardedAd) {
print("広告表示予定")
// BGMの一時停止など
}
// オプション: フルスクリーン広告表示完了
func onAdDidPresentFullScreen(_ ad: AdropRewardedAd) {
print("広告表示完了")
}
// オプション: フルスクリーン広告閉じる直前
func onAdWillDismissFullScreen(_ ad: AdropRewardedAd) {
print("広告閉じる予定")
}
// オプション: フルスクリーン広告閉じた後
func onAdDidDismissFullScreen(_ ad: AdropRewardedAd) {
print("広告画面を閉じた")
// BGMの再開など
// 次の広告を事前読み込み
rewardedAd?.load()
}
// オプション: 広告表示失敗
func onAdFailedToShowFullScreen(_ ad: AdropRewardedAd, _ errorCode: AdropErrorCode) {
print("広告表示失敗: \(errorCode)")
}
}
SwiftUI例
import SwiftUI
import AdropAds
class RewardedAdViewModel: NSObject, ObservableObject, AdropRewardedAdDelegate {
@Published var isAdReady = false
@Published var showingAlert = false
@Published var alertMessage = ""
private var rewardedAd: AdropRewardedAd?
override init() {
super.init()
loadAd()
}
func loadAd() {
rewardedAd = AdropRewardedAd(unitId: "YOUR_UNIT_ID")
rewardedAd?.delegate = self
rewardedAd?.load()
}
func showAd() {
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let rootViewController = windowScene.windows.first?.rootViewController else {
return
}
rewardedAd?.show(fromRootViewController: rootViewController) { [weak self] type, amount in
self?.alertMessage = "報酬獲得! タイプ: \(type), 数量: \(amount)"
self?.showingAlert = true
self?.grantReward(type: type, amount: amount)
}
}
private func grantReward(type: Int, amount: Int) {
// 報酬付与処理
print("報酬付与 - タイプ: \(type), 数量: \(amount)")
}
// MARK: - AdropRewardedAdDelegate
func onAdReceived(_ ad: AdropRewardedAd) {
isAdReady = true
}
func onAdFailedToReceive(_ ad: AdropRewardedAd, _ errorCode: AdropErrorCode) {
isAdReady = false
alertMessage = "広告読み込み失敗: \(errorCode)"
showingAlert = true
}
func onAdDidDismissFullScreen(_ ad: AdropRewardedAd) {
isAdReady = false
// 次の広告を事前読み込み
loadAd()
}
func onAdFailedToShowFullScreen(_ ad: AdropRewardedAd, _ errorCode: AdropErrorCode) {
alertMessage = "広告表示失敗: \(errorCode)"
showingAlert = true
}
}
struct RewardedAdView: View {
@StateObject private var viewModel = RewardedAdViewModel()
var body: some View {
VStack(spacing: 20) {
Text("リワード広告サンプル")
.font(.title)
Button(action: {
viewModel.showAd()
}) {
Text("動画を見て報酬を獲得")
.padding()
.background(viewModel.isAdReady ? Color.blue : Color.gray)
.foregroundColor(.white)
.cornerRadius(8)
}
.disabled(!viewModel.isAdReady)
}
.alert(isPresented: $viewModel.showingAlert) {
Alert(
title: Text("通知"),
message: Text(viewModel.alertMessage),
dismissButton: .default(Text("確認"))
)
}
}
}
Objective-C例
@import AdropAds;
@interface RewardedViewController () <AdropRewardedAdDelegate>
@property (nonatomic, strong) AdropRewardedAd *rewardedAd;
@end
@implementation RewardedViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 1. AdropRewardedAdインスタンスの生成
self.rewardedAd = [[AdropRewardedAd alloc] initWithUnitId:@"YOUR_UNIT_ID"];
// 2. デリゲートの設定
self.rewardedAd.delegate = self;
// 3. 広告の読み込み
[self.rewardedAd load];
}
- (IBAction)showRewardedAdButtonTapped:(UIButton *)sender {
// 広告が読み込まれたか確認
if (!self.rewardedAd.isLoaded) {
NSLog(@"広告がまだ読み込まれていません");
return;
}
// 4. 広告の表示と報酬処理
__weak typeof(self) weakSelf = self;
[self.rewardedAd showFromRootViewController:self
userDidEarnRewardHandler:^(NSInteger type, NSInteger amount) {
NSLog(@"報酬獲得 - タイプ: %ld, 数量: %ld", (long)type, (long)amount);
[weakSelf grantRewardWithType:type amount:amount];
}];
}
- (void)grantRewardWithType:(NSInteger)type amount:(NSInteger)amount {
// ユーザーに報酬を付与
}
#pragma mark - AdropRewardedAdDelegate
// 必須: 広告受信成功
- (void)onAdReceived:(AdropRewardedAd *)ad {
NSLog(@"広告受信完了");
}
// 必須: 広告受信失敗
- (void)onAdFailedToReceive:(AdropRewardedAd *)ad :(AdropErrorCode)errorCode {
NSLog(@"広告受信失敗: %ld", (long)errorCode);
}
// オプション: 広告表示
- (void)onAdImpression:(AdropRewardedAd *)ad {
NSLog(@"広告表示");
}
// オプション: 広告クリック
- (void)onAdClicked:(AdropRewardedAd *)ad {
NSLog(@"広告クリック");
}
// オプション: フルスクリーン広告表示直前
- (void)onAdWillPresentFullScreen:(AdropRewardedAd *)ad {
NSLog(@"広告表示予定");
}
// オプション: フルスクリーン広告表示完了
- (void)onAdDidPresentFullScreen:(AdropRewardedAd *)ad {
NSLog(@"広告表示完了");
}
// オプション: フルスクリーン広告閉じる直前
- (void)onAdWillDismissFullScreen:(AdropRewardedAd *)ad {
NSLog(@"広告閉じる予定");
}
// オプション: フルスクリーン広告閉じた後
- (void)onAdDidDismissFullScreen:(AdropRewardedAd *)ad {
NSLog(@"広告画面を閉じた");
// 次の広告を事前読み込み
[self.rewardedAd load];
}
// オプション: 広告表示失敗
- (void)onAdFailedToShowFullScreen:(AdropRewardedAd *)ad :(AdropErrorCode)errorCode {
NSLog(@"広告表示失敗: %ld", (long)errorCode);
}
@end
デリゲートメソッド
必須メソッド
void
広告の受信に成功したときに呼び出されます。この時点から
show()メソッドで広告を表示できます。void
広告の受信に失敗したときに呼び出されます。エラーコードで失敗原因を確認できます。
オプションメソッド
void
広告が表示され、表示記録が送信されたときに呼び出されます。
void
ユーザーが広告をクリックしたときに呼び出されます。
void
広告画面が表示される直前に呼び出されます。BGMの一時停止などの処理ができます。
void
広告画面が完全に表示された後に呼び出されます。
void
広告画面が閉じる直前に呼び出されます。
void
広告画面が完全に閉じた後に呼び出されます。BGMの再開や次の広告の事前読み込みができます。
void
広告の表示に失敗したときに呼び出されます。エラーコードで失敗原因を確認できます。
クロージャコールバック
デリゲートの代わりにクロージャベースのコールバックを使用できます。let rewardedAd = AdropRewardedAd(unitId: "YOUR_UNIT_ID")
// 必須
rewardedAd.onAdReceived = { ad in
print("広告受信成功")
}
rewardedAd.onAdFailedToReceive = { ad, errorCode in
print("広告受信失敗: \(errorCode)")
}
// オプション
rewardedAd.onAdImpression = { ad in print("広告表示") }
rewardedAd.onAdClicked = { ad in print("広告クリック") }
rewardedAd.onAdWillPresentFullScreen = { ad in print("広告表示直前") }
rewardedAd.onAdDidPresentFullScreen = { ad in print("広告表示完了") }
rewardedAd.onAdWillDismissFullScreen = { ad in print("広告閉じる直前") }
rewardedAd.onAdDidDismissFullScreen = { ad in print("広告閉じた") }
rewardedAd.onAdFailedToShowFullScreen = { ad, errorCode in print("広告表示失敗: \(errorCode)") }
デリゲートとクロージャの両方を設定すると、両方が呼び出されます。
報酬処理
報酬コールバック
show()メソッドのuserDidEarnRewardHandlerパラメータで報酬コールバックを渡します。
rewardedAd?.show(fromRootViewController: self) { type, amount in
// type: 報酬タイプ (Int)
// amount: 報酬数量 (Int)
print("報酬獲得 - タイプ: \(type), 数量: \(amount)")
}
報酬タイプと数量
- type: Adropコンソールで設定した報酬タイプ (整数値)
- amount: Adropコンソールで設定した報酬数量 (整数値)
サーバーサイド検証
サーバーサイド検証(SSV)を使用すると、サーバーで報酬付与を検証でき、クライアント側の改ざんを防止できます。AdropServerSideVerificationOptionsを使用して、サーバー間コールバックに含まれるユーザー識別情報とカスタムデータを渡します。
サーバーでSSVコールバックを受信するには、コンソールの**[管理] > [連携] > リワード広告SSV**でコールバックURLを登録してください。ここで設定した
userIdとcustomDataは、そのURLへ送信される暗号化ペイロードに含まれます。ペイロードの復号と設定方法はリワード広告SSVガイドをご参照ください。SSVの設定
let rewardedAd = AdropRewardedAd(unitId: "YOUR_UNIT_ID")
rewardedAd.delegate = self
// 広告の読み込み前にサーバーサイド検証オプションを設定
let ssvOptions = AdropServerSideVerificationOptions(
userId: "user_12345",
customData: "extra_info"
)
rewardedAd.serverSideVerificationOptions = ssvOptions
rewardedAd.load()
AdropServerSideVerificationOptions
| プロパティ | 型 | 説明 |
|---|---|---|
userId | String? | サーバーサイド検証用のユーザー識別子 |
customData | String? | コールバックに含めるカスタムデータ文字列 |
// パラメータで初期化
let options = AdropServerSideVerificationOptions(
userId: "user_12345",
customData: "level_5_reward"
)
// または個別にプロパティを設定
let options = AdropServerSideVerificationOptions()
options.userId = "user_12345"
options.customData = "level_5_reward"
rewardedAd.serverSideVerificationOptions = options
load()を呼び出す前にserverSideVerificationOptionsを設定してください。userIdとcustomDataの値は、ユーザーが報酬を獲得したときにサーバーコールバックURLに送信されます。ベストプラクティス
1. 広告の事前読み込み
ユーザー体験のために広告を事前に読み込んでおくことをお勧めします。class GameViewController: UIViewController {
private var rewardedAd: AdropRewardedAd?
override func viewDidLoad() {
super.viewDidLoad()
// 画面進入時に広告を事前読み込み
loadRewardedAd()
}
private func loadRewardedAd() {
rewardedAd = AdropRewardedAd(unitId: "YOUR_UNIT_ID")
rewardedAd?.delegate = self
rewardedAd?.load()
}
private func showRewardedAd() {
rewardedAd?.show(fromRootViewController: self) { [weak self] type, amount in
self?.grantReward(type: type, amount: amount)
}
}
}
extension GameViewController: AdropRewardedAdDelegate {
func onAdReceived(_ ad: AdropRewardedAd) {
print("リワード広告準備完了")
}
func onAdFailedToReceive(_ ad: AdropRewardedAd, _ errorCode: AdropErrorCode) {
print("広告読み込み失敗: \(errorCode)")
}
func onAdDidDismissFullScreen(_ ad: AdropRewardedAd) {
// 広告が閉じた後、次の広告を事前読み込み
loadRewardedAd()
}
}
2. 広告準備状態の確認
広告が読み込まれたかを確認し、UIを更新します。class GameViewController: UIViewController {
@IBOutlet weak var watchAdButton: UIButton!
private var rewardedAd: AdropRewardedAd?
private var isAdReady = false
private func updateButtonState() {
watchAdButton.isEnabled = isAdReady
watchAdButton.alpha = isAdReady ? 1.0 : 0.5
watchAdButton.setTitle(
isAdReady ? "動画を見てライフを獲得" : "広告読み込み中...",
for: .normal
)
}
}
extension GameViewController: AdropRewardedAdDelegate {
func onAdReceived(_ ad: AdropRewardedAd) {
isAdReady = true
updateButtonState()
}
func onAdFailedToReceive(_ ad: AdropRewardedAd, _ errorCode: AdropErrorCode) {
isAdReady = false
updateButtonState()
}
func onAdDidDismissFullScreen(_ ad: AdropRewardedAd) {
isAdReady = false
updateButtonState()
// 次の広告を読み込み
rewardedAd?.load()
}
}
3. BGM処理
広告表示前後でBGMを適切に制御します。extension GameViewController: AdropRewardedAdDelegate {
func onAdReceived(_ ad: AdropRewardedAd) { }
func onAdFailedToReceive(_ ad: AdropRewardedAd, _ errorCode: AdropErrorCode) { }
func onAdWillPresentFullScreen(_ ad: AdropRewardedAd) {
// 広告表示直前にBGMを一時停止
AudioManager.shared.pauseBackgroundMusic()
}
func onAdDidDismissFullScreen(_ ad: AdropRewardedAd) {
// 広告終了後にBGMを再開
AudioManager.shared.resumeBackgroundMusic()
}
}
4. エラー処理
広告読み込み失敗時のリトライロジックを実装します。extension GameViewController: AdropRewardedAdDelegate {
func onAdFailedToReceive(_ ad: AdropRewardedAd, _ errorCode: AdropErrorCode) {
print("広告読み込み失敗: \(errorCode)")
// ネットワークエラーの場合リトライ
if errorCode == .ERROR_CODE_NETWORK {
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) { [weak self] in
self?.rewardedAd?.load()
}
}
}
func onAdFailedToShowFullScreen(_ ad: AdropRewardedAd, _ errorCode: AdropErrorCode) {
print("広告表示失敗: \(errorCode)")
// ユーザーに通知
showAlert(message: "広告を表示できません。後でもう一度お試しください。")
}
}
5. メモリ管理
ViewControllerが解放されるとき、広告オブジェクトもクリーンアップします。class GameViewController: UIViewController {
private var rewardedAd: AdropRewardedAd?
deinit {
rewardedAd?.delegate = nil
rewardedAd = nil
}
}
テスト
テストユニットID
開発中は必ずテストユニットIDを使用してください。// 開発環境
let rewardedAd = AdropRewardedAd(unitId: "PUBLIC_TEST_UNIT_ID_REWARDED")
// 本番環境
let rewardedAd = AdropRewardedAd(unitId: "YOUR_PRODUCTION_UNIT_ID")
実際のユニットIDでテストすると、無効なトラフィックと見なされ、アカウントが停止される可能性があります。必ずテストユニットIDを使用してください。
環境別ユニットID管理
ビルド設定に応じてユニットIDを自動的に切り替える方法です。enum AdUnitID {
static var rewarded: String {
#if DEBUG
return "PUBLIC_TEST_UNIT_ID_REWARDED"
#else
return "YOUR_PRODUCTION_UNIT_ID"
#endif
}
}
// 使用方法
let rewardedAd = AdropRewardedAd(unitId: AdUnitID.rewarded)
関連ドキュメント
インタースティシャル広告
インタースティシャル広告実装ガイド
エラーコード
AdropErrorCodeリファレンス
サンプルプロジェクト
全体のサンプルコードを見る