AdMob動画リワード広告の導入手順

iPhoneアプリにAdMobの動画リワード広告を表示するサンプルを作成しました。

公式リファレンスを参考にさせていただきました。ご使用の際はアプリIDと広告枠IDを指定してください。

下記よりサンプルをダウンロード出来ますので、導入の際のお役に立てば幸いです。

ダウンロード

導入準備

1. Info.plistの編集

AdMobのサイトからアプリIDを取得し、Info.plistGADApplicationIdentifierの項目を追加し指定してください。

2. 広告枠IDの保持

1
NSString *const GAD_REWARD_UNIT_ID = @"広告枠ID";

3. アプリ起動時に初期化

AppDelegate.h

1
@import GoogleMobileAds;

AppDelegate.m

1
2
3
4
5
6
7
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // AdMobアプリID初期化
    [[GADMobileAds sharedInstance] startWithCompletionHandler:nil];

    return YES;
}

動画リワード広告の読み込み

1
[[AdMobRewardedVideoAds sharedManager] loadRewardedVideoAds:self usePersonalizedAds:YES];

ソースコード

AdMobRewardedVideoAds.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#import <Foundation/Foundation.h>

@import GoogleMobileAds;

@interface AdMobRewardedVideoAds : NSObject <GADRewardedAdDelegate> {
    BOOL isCompletePlaying;
}

#pragma mark - property
@property (nonatomic, strong) GADRewardedAd    *adMobRewardedAd;
@property (nonatomic, strong) UIViewController *rootViewController;
@property (nonatomic, assign) BOOL             usePersonalizedAds;

@property (nonatomic, retain) UIActivityIndicatorView *activityIndicator;
@property (nonatomic, retain) UIView                  *overlay;
@property (nonatomic, assign) BOOL                    showOverlay;

#pragma mark - enumerator
typedef NS_ENUM(NSUInteger, activityIndicatorStyles) {
    AI_GRAY        = 1,
    AI_WHITE       = 2,
    AI_WHITE_LARGE = 3
};

#pragma mark - public method
+ (id)sharedManager;
- (void)loadRewardedVideoAds:(UIViewController *)viewController usePersonalizedAds:(BOOL)usePersonalizedAds;

@end

AdMobRewardedVideoAds.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#import "AdMobRewardedVideoAds.h"

@implementation AdMobRewardedVideoAds

#pragma mark - Shared Manager

static id sharedInstance = nil;

+ (id)sharedManager
{
    @synchronized(self) {
        if (!sharedInstance) {
            sharedInstance = [[self alloc] init];
        }
    }

    return sharedInstance;
}

#pragma mark - AdMob Rewarded Video Ads

// AdMob動画リワード広告広告読み込み
- (void)loadRewardedVideoAds:(UIViewController *)viewController usePersonalizedAds:(BOOL)usePersonalizedAds
{
    if (![viewController isEqual:self.rootViewController]) {
        self.rootViewController = viewController;
    }

    self.usePersonalizedAds = usePersonalizedAds;

    self.adMobRewardedAd = [[GADRewardedAd alloc] initWithAdUnitID:GAD_TEST_MODE ? GAD_REWARD_TEST_UNIT_ID : GAD_REWARD_UNIT_ID];

    GADRequest *request = [GADRequest request];
    if (GAD_TEST_MODE) {
        [[GADMobileAds sharedInstance] requestConfiguration].testDeviceIdentifiers = @[kGADSimulatorID,
                                                                                       @"Test Device ID"];
    }

    if (!self.usePersonalizedAds) {
        GADExtras *extras = [[GADExtras alloc] init];
        extras.additionalParameters = @{@"npa": @"1"};
        [request registerAdNetworkExtras:extras];
    }
    //NSLog(@"RewardedVideoAds -> usePersonalizedAds: %d", self.usePersonalizedAds);

    [self.adMobRewardedAd loadRequest:request completionHandler:^(GADRequestError * _Nullable error) {
      if (error) {
          // 再生完了フラグを下ろす
          self->isCompletePlaying = NO;

          // アクティビティインジケーターのアニメーション停止
          [self stopActivityIndicator];
      } else {
          //NSLog(@"Reward based video ad is received.");

          // 動画リワード広告表示
          if (self.adMobRewardedAd.isReady) {
              [self.adMobRewardedAd presentFromRootViewController:self.rootViewController delegate:self];
          }

          // アクティビティインジケーターのアニメーション停止
          [self stopActivityIndicator];
      }
    }];

    // アクティビティインジケータのアニメーション開始
    CGFloat const screenWidth  = [[UIScreen mainScreen] bounds].size.width;
    CGFloat const screenHeight = [[UIScreen mainScreen] bounds].size.height;
    [self startActivityIndicator:self.rootViewController.view center:CGPointMake(screenWidth / 2, screenHeight / 2)
                         styleId:AI_WHITE hidesWhenStopped:YES showOverlay:YES];

    // 再生完了フラグを下ろす
    isCompletePlaying = NO;
}

// リワード提供
- (void)rewardedAd:(GADRewardedAd *)rewardedAd userDidEarnReward:(GADAdReward *)reward
{
    //NSLog(@"rewardedAd:userDidEarnReward:");

    // TODO: リワード提供


    // 再生完了フラグを立てる
    isCompletePlaying = YES;
}

// 動画リワード広告が開かれた時に呼ばれる
- (void)rewardedAdDidPresent:(GADRewardedAd *)rewardedAd
{
    //NSLog(@"rewardedAdDidPresent:");

    // 再生完了フラグを下ろす
    isCompletePlaying = NO;
}

// 動画リワード広告がエラーで開かれなかった時に呼ばれる
- (void)rewardedAd:(GADRewardedAd *)rewardedAd didFailToPresentWithError:(NSError *)error
{
    //NSLog(@"rewardedAd:didFailToPresentWithError");

    // 再生完了フラグを下ろす
    isCompletePlaying = NO;

    // アクティビティインジケーターのアニメーション停止
    [self stopActivityIndicator];
}

// 動画リワード広告が閉じられた時に呼ばれる
- (void)rewardedAdDidDismiss:(GADRewardedAd *)rewardedAd
{
    //NSLog(@"rewardedAd:rewardedAdDidDismiss");

    // TODO: 再生が完了していればお知らせアラート表示
    if (isCompletePlaying) {

    }
}

#pragma mark - Activity Indicator

// アクティビティインジケーターのアニメーション開始
- (void)startActivityIndicator:(id)view center:(CGPoint)center styleId:(NSInteger)styleId hidesWhenStopped:(BOOL)hidesWhenStopped showOverlay:(BOOL)showOverlay
{
    // インジケーター初期化
    _activityIndicator = [[UIActivityIndicatorView alloc] init];

    // スタイルを設定
    switch (styleId) {
        case AI_GRAY:
            _activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;

            break;
        case AI_WHITE:
            _activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;

            break;
        case AI_WHITE_LARGE:
            _activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;

            break;
    }

    // スタイルに応じて寸法変更
    if (_activityIndicator.activityIndicatorViewStyle == UIActivityIndicatorViewStyleWhiteLarge) {
        _activityIndicator.frame = CGRectMake(0, 0, 50.0, 50.0);
    } else {
        _activityIndicator.frame = CGRectMake(0, 0, 20.0, 20.0);
    }

    // 座標をセンターに指定
    _activityIndicator.center = center;

    // 停止した時に隠れるよう設定
    _activityIndicator.hidesWhenStopped = hidesWhenStopped;

    // インジケーターアニメーション開始
    [_activityIndicator startAnimating];

    // オーバーレイ表示フラグ保持
    _showOverlay = showOverlay;

    // オーバーレイ表示
    if (_showOverlay) {
        _overlay = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        _overlay.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.5f];
        [view addSubview:_overlay];
    }

    // 画面に追加
    [view addSubview:_activityIndicator];
}

// アクティビティインジケーターのアニメーション停止
- (void)stopActivityIndicator
{
    if (_showOverlay) {
        [_overlay removeFromSuperview];
    }
    [_activityIndicator stopAnimating];
}

@end

リワードの提供

当方は動画リワード広告が最後まで再生されたら3日間広告を表示しないという設定にしています。

また、リワードが提供されたことをユーザーにお知らせするため、リワード期限日を文字列で取得できるようにしています。

まず下記のようにリワードを提供します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// 動画リワード広告再生完了時の処理
+ (void)onCompleteRewardedVideoAds
{
    // 視聴済みフラグを立てる
    [Common sharedManager].isRewarded = YES;

    // ユーザーデフォルト更新
    [[Common sharedManager].userDefaults setBool:[Common sharedManager].isRewarded forKey:UD_REWARDED_KEY];
    [[Common sharedManager].userDefaults synchronize];

    // リワード受取日と期限日の保存
    NSDate *const rewardDateReceived   = [NSDate date];
    NSDate *const rewardExpirationDate = [Common rewardExpirationDate];

    [[Common sharedManager].userDefaults setObject:rewardDateReceived forKey:UD_REWARD_DATE_RECEIVED_KEY];
    [[Common sharedManager].userDefaults setObject:rewardExpirationDate forKey:UD_REWARD_EXPIRATION_KEY];
    [[Common sharedManager].userDefaults synchronize];

    // TODO: バナー削除

}

// リワード期限日の取得
+ (NSDate *)rewardExpirationDate
{
    NSDate *const rewardDateReceived = [NSDate date];

    return [rewardDateReceived initWithTimeInterval:[Common sharedManager].rewardPeriod * 24 * 60 * 60 sinceDate:rewardDateReceived];
}

// リワード期限日を文字列で取得
+ (NSString *)rewardExpirationDateStr
{
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setLocale:[NSLocale systemLocale]];
    [dateFormatter setDateFormat:@"yyyy/MM/dd HH:mm:ss"];

    NSDate   *const expirationDate    = [Common rewardExpirationDate];
    NSString *const expirationDateStr = [dateFormatter stringFromDate:expirationDate];

    return [NSString stringWithFormat:@"(有効期限: %@)", expirationDateStr];
}

リワード期間中であるか判定

アプリ起動時にリワード期間中であるか判定し、フラグを更新します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // リワード期間であれば期限切れであるか判定
    if ([Common sharedManager].isRewarded) {
        // リワード受取日とリワード期限日の取得
        NSDate *const rewardDateReceived   = [[Common sharedManager].userDefaults objectForKey:UD_REWARD_DATE_RECEIVED_KEY];
        NSDate *const rewardExpirationDate = [[Common sharedManager].userDefaults objectForKey:UD_REWARD_EXPIRATION_KEY];

        // 現在時刻がリワード期間であるか判定
        NSDate *const now = [NSDate date];
        [Common sharedManager].isRewarded = [now compare:rewardDateReceived] == NSOrderedDescending && [now compare:rewardExpirationDate] == NSOrderedAscending;

        // ユーザーデフォルト更新
        [[Common sharedManager].userDefaults setBool:[Common sharedManager].isRewarded forKey:UD_REWARDED_KEY];
        [[Common sharedManager].userDefaults synchronize];
    }

    return YES;
}

以上で動画リワード広告の実装は完了になります。

関連記事

About

廣川政樹 (@dolice_apps)

テクニカルアーティスト 廣川政樹の開発ブログ。Objective-Cや Javaなど iPhone/Androidアプリ開発に関する技術情報を掲載しています。

iPhone apps

  • リラックス・ヒーリング
  • 望みが叶う!引き寄せの法則アプリ
  • 泣ける話 - 感動のエピソードまとめ - ラクリマ
  • ミステリー - 怖い話や不思議な体験、都市伝説まとめ
  • 浮世絵壁紙 - 美しい日本画ギャラリー
  • 綺麗な壁紙

Android apps

  • 浮世絵壁紙 - 美しい日本画ギャラリー
  • 綺麗な高画質壁紙

Objective-C Classes

Tag Cloud

ActionScript(9) ActionScript3(7) Ad(5) Adfurikun(2) AdMob(12) Android(11) Animation(17) AppDelegate(3) ARC(1) ArrayList(1) AVAudioPlayer(4) AVAudioSession(1) AVFoundation(3) Banner(2) Bitmap(1) Camera(4) CGAffineTransform(4) CGBlendMode(2) CGContextRef(1) CGImageRef(1) Classes(49) CLLocationManager(1) ConnectivityManager(1) ContentResolver(1) CoreLocation(2) Delegate(3) Device(7) Display(1) DisplayMetrics(1) Download(109) Facebook(6) Foundation(72) Framework(2) Google Analytics(1) Handler(1) iAd(6) ImageView(1) In-AppPurchase(1) iOS(12) iOS 7(15) iOS 7.1(3) iOS 8(1) iPad(7) iPhone(24) iPhone 6(4) Java(7) JavaScript(2) LINE(4) Localize(1) Magazine(3) MediaStore(1) MFComposeViewController(1) Nend(1) NetworkInfo(1) NSArray(23) NSCalendar(3) NSData(2) NSDate(7) NSDateComponents(2) NSDateFormatter(2) NSDictionary(12) NSEnumerator(1) NSIndexSet(1) NSInteger(6) NSMutableArray(17) NSMutableDictionary(5) NSMutableOrderedSet(7) NSMutableString(4) NSMutableURLRequest(1) NSNotificationCenter(1) NSNumber(1) NSObject(1) NSOrderedSet(7) NSRange(2) NSSelectorFromString(1) NSSet(6) NSString(19) NSTimer(4) NSTimeZone(1) NSURL(7) NSURLConnection(1) NSURLRequest(2) NSUserDefaults(7) NSXMLParser(2) Objective-C(229) PHP(1) Products(17) QuartzCore(3) RSS(2) Runnable(1) Sample(51) Screensaver(9) SDK(2) ShareCompat(1) Social(10) StoreKit(1) Twitter(6) UIAccelerometer(3) UIActionSheet(1) UIActivityIndicator(1) UIActivityIndicatorView(3) UIActivityViewController(1) UIAlertView(5) UIApplication(7) UIButton(4) UIColor(3) UIDatePicker(5) UIDevice(6) UIDeviceOrientation(1) UIEvent(6) UIImage(15) UIImagePickerController(4) UIImageView(12) UIKit(58) UILabel(7) UINavigationBar(4) UINavigationItem(1) UIPasteboard(4) UIScreen(1) UIScrollBar(1) UIScrollView(1) UISlider(3) UIStoryboardSegue(3) UISwitch(1) UITabBar(3) UITableView(4) UITextField(2) UIView(11) UIViewAnimationTransition(1) UIViewController(4) UIWebView(5) Uncategorized(1) UserNotifications(1) WindowManager(1) Xcode(48) Xcode 5(8) Xcode 5.1(2)