iOSアプリでローカルプッシュ通知を使用する

iOSアプリで指定した時刻にローカルプッシュ通知を送信する手順を以下に記載します。

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

ダウンロード

使用手順

1. Frameworkの追加

今回のサンプルは iOS 10以降を対象としていますので、UserNotifications.frameworkをプロジェクトに追加します。

2. プッシュ通知の許可をユーザーに求める

ローカルプッシュ通知の送信には、アプリ起動時にユーザーに対しプッシュ通知の受信許可を求める必要があります。

AppDelegate.h

1
@import UserNotifications;

AppDelegate.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// アプリ起動時の処理
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // ユーザーにプッシュ通知の許可を求める
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert)
                          completionHandler:^(BOOL granted, NSError * _Nullable error) {
        if (!error) {
            NSLog(@"Succeeded!");
        }
    }];

    return YES;
}

3. ローカルプッシュ通知管理クラスの作成

今回のサンプルでは、指定した時刻にローカルプッシュ通知を送信するよう実装しています。

LocalNotificationManager.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#import <UIKit/UIKit.h>

@import UserNotifications;

NS_ASSUME_NONNULL_BEGIN

@interface LocalNotificationManager : NSObject

#pragma mark - property
@property (nonatomic, strong) NSCalendar *calendar;
@property (nonatomic, strong) NSDate     *nowDate;

#pragma mark - public method
- (void)scheduleLocalNotifications:(NSArray *)notificationHours;

@end

NS_ASSUME_NONNULL_END

LocalNotificationManager.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
#import "LocalNotificationManager.h"

@implementation LocalNotificationManager

#pragma mark - Scheduler

// ローカルプッシュ通知のスケジューリング
- (void)scheduleLocalNotifications:(NSArray *)notificationHours
{
    // 通知を全てキャンセルする
    [[UNUserNotificationCenter currentNotificationCenter] removeAllPendingNotificationRequests];

    // 通知時間を設定する
    for (int i = 0; i < [notificationHours count]; i++) {
        // 通知時間保持
        NSUInteger notificationHour = [notificationHours[i] intValue];

        // カレンダー初期化
        _calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];

        // 現在の日付取得
        _nowDate  = [NSDate date];

        // コンポーネント初期化
        NSDateComponents *fireDateComponents = [_calendar components:(NSCalendarUnitHour |
                                                                      NSCalendarUnitMinute |
                                                                      NSCalendarUnitSecond)
                                                            fromDate:_nowDate];

        // コンポーネントに通知時間を指定
        [fireDateComponents setHour:notificationHour];
        [fireDateComponents setMinute:0];
        [fireDateComponents setSecond:0];
        [fireDateComponents setTimeZone:[NSTimeZone systemTimeZone]];

        // ローカル通知のスケジュール呼び出し
        [self makeNotification:fireDateComponents notificationHour:notificationHour userInfo:nil];
    }
}

// ローカルプッシュ通知生成
- (void)makeNotification:(NSDateComponents *)fireDateComponents notificationHour:(NSUInteger)notificationHour userInfo:(NSDictionary *)userInfo
{
    // デバッグ出力
    //NSLog(@"fireDateComponents: %@", fireDateComponents);

    // ローカルプッシュ通知のスケジューリング
    UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
    content.title    = @"It's time to go.";
    content.body     = [NSString stringWithFormat:@"t's now %lu:00.", notificationHour];
    content.sound    = [UNNotificationSound defaultSound];
    content.badge    = @([[UIApplication sharedApplication] applicationIconBadgeNumber] + 1);
    content.userInfo = userInfo;

    UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger
                                              triggerWithDateMatchingComponents:fireDateComponents repeats:YES];

    NSString *const notificationIdentifier = [NSString stringWithFormat:@"NotificationHour: %lu", notificationHour];

    UNNotificationRequest *request = [UNNotificationRequest
                                      requestWithIdentifier:notificationIdentifier content:content trigger:trigger];

    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
        if (error != nil) {
            NSLog(@"%@", error);
        }
    }];
}

4. プッシュ通知の予約

ユーザーがアプリを閉じたタイミングでプッシュ通知を予約します。今回は9時、12時、15時、18時にローカルプッシュ通知が送信されるよう指定しました。

AppDelegate.h

1
#import "LocalNotificationManager.h"

AppDelegate.m

1
2
3
4
5
6
7
8
9
10
// アプリがバックグラウンドになった時に呼ばれる
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // ローカルプッシュ通知を送信する時間を指定
    NSArray *notificationHours = @[@9, @12, @15, @18];

    // バックグラウンド移行時にプッシュ通知を設定
    LocalNotificationManager *notificationManager = [[LocalNotificationManager alloc] init];
    [notificationManager scheduleLocalNotifications:notificationHours];
}

e.x. アイコンバッジの削除

このサンプルではプッシュ通知送信時にアイコンバッジを付与するよう指定していますので、アプリが起動されたらアイコンバッジを削除するようにします。

AppDelegate.m

1
2
3
4
5
6
// アプリがバックグラウンドからフォアグラウンドになる直前に呼ばれる
- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // アイコンバッジ削除
    [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
}

以上でローカルプッシュ通知の実装は完了になります。

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;
}

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

関連記事

AdMobバナーを表示する「DCAdMobBanner」クラス(改訂版)

iPhoneアプリにAdMobのモバイルバナーを表示する「DCAdMobBanner」クラスを改訂しました。

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

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

ダウンロード

今回の変更点

  1. バナーのフェードイン秒数を指定できるようにしました
  2. アダプティブバナーを使用するか指定できるようにしました
  3. 広告のパーソナライズ設定を使用するか指定できるようにしました

導入準備

1. Info.plistの編集

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

2. 広告枠IDの保持

1
NSString *const GAD_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. バナーの表示

1
2
[[DCAdMobBanner sharedManager] showAdBanner:self yPos:0.0 fadeInDuration:0.0
                              useAdaptiveBanner:YES useSmartBanner:NO usePersonalizedAds:YES];

2. バナーの削除

1
[[DCAdMobBanner sharedManager] removeAdBanner];

3. バナーの非表示

1
[[DCAdMobBanner sharedManager] hideAdBanner:YES];

4. バナーを最前面に配置

1
[[DCAdMobBanner sharedManager] insertAdBanner];

5. バナーの再読み込み

1
[[DCAdMobBanner sharedManager] reloadAdBanner:self usePersonalizedAds:YES];

6. ロード状況の取得

1
BOOL isLoadedAdBanner = [[DCAdMobBanner sharedManager] loaded];

ソースコード

DCAdMobBanner.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 DCAdMobBanner : NSObject <GADBannerViewDelegate> {
    CGFloat bannerX;
    CGFloat bannerY;
    BOOL    isFailed;
}

#pragma mark - property
@property (nonatomic, strong) GADBannerView    *gadView;
@property (nonatomic, strong) UIViewController *currentRootViewController;
@property (nonatomic, assign) BOOL             loaded;
@property (nonatomic, assign) CGFloat          fadeInDuration;
@property (nonatomic, assign) BOOL             useAdaptiveBanner;
@property (nonatomic, assign) BOOL             useSmartBanner;
@property (nonatomic, assign) BOOL             usePersonalizedAds;

#pragma mark - public method
+ (id)sharedManager;
- (void)showAdBanner:(UIViewController *)viewController yPos:(CGFloat)yPos fadeInDuration:(CGFloat)fadeInDuration
   useAdaptiveBanner:(BOOL)useAdaptiveBanner useSmartBanner:(BOOL)useSmartBanner usePersonalizedAds:(BOOL)usePersonalizedAds;
- (void)reloadAdBanner:(UIViewController *)viewController usePersonalizedAds:(BOOL)usePersonalizedAds;
- (void)removeAdBanner;
- (void)hideAdBanner:(BOOL)hidden;
- (void)insertAdBanner;

@end

DCAdMobBanner.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
#import "DCAdMobBanner.h"

@implementation DCAdMobBanner

@synthesize gadView                   = _gadView;
@synthesize currentRootViewController = _currentRootViewController;
@synthesize loaded                    = _loaded;

#pragma mark - Shared Manager

static id sharedInstance = nil;

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

    return sharedInstance;
}

#pragma mark - public method

// バナー表示
- (void)showAdBanner:(UIViewController *)viewController yPos:(CGFloat)yPos fadeInDuration:(CGFloat)fadeInDuration
   useAdaptiveBanner:(BOOL)useAdaptiveBanner useSmartBanner:(BOOL)useSmartBanner usePersonalizedAds:(BOOL)usePersonalizedAds
{
    self.currentRootViewController = viewController;
    self.fadeInDuration = fadeInDuration;
    self.useAdaptiveBanner = useAdaptiveBanner;
    self.useSmartBanner = useSmartBanner;
    self.usePersonalizedAds = usePersonalizedAds;

    if (!self.useAdaptiveBanner && !self.useSmartBanner) {
        CGFloat const screenWidth = [[UIScreen mainScreen] bounds].size.width;
        bannerX = roundf((screenWidth / 2) - (kGADAdSizeBanner.size.width / 2));
    }
    bannerY = yPos;

    [self showAdMobBanner:viewController.view];
}

// バナーの再読み込み
- (void)reloadAdBanner:(UIViewController *)viewController usePersonalizedAds:(BOOL)usePersonalizedAds
{
    self.currentRootViewController = viewController;
    self.usePersonalizedAds = usePersonalizedAds;

    if (self.gadView.superview) {
        [self loadAdMobBanner:self.currentRootViewController.view];
    }
}

// バナー削除
- (void)removeAdBanner
{
    if (self.gadView.superview) {
        [self.gadView removeFromSuperview];
    }
}

// バナー非表示
- (void)hideAdBanner:(BOOL)hidden
{
    if (self.gadView.superview) {
        self.gadView.hidden = hidden;
    }
}

// バナーを最前面に配置
- (void)insertAdBanner
{
    if (self.gadView.superview) {
        NSUInteger subviewsCount = [[self.currentRootViewController.view subviews] count];
        [self.currentRootViewController.view insertSubview:self.gadView atIndex:subviewsCount + 1];
    }
}

#pragma mark - AdMob Banner

- (void)showAdMobBanner:(UIView *)targetView
{
    if (!self.gadView) {
        if (self.useAdaptiveBanner) {
            self.gadView = [[GADBannerView alloc] initWithAdSize:GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(targetView.frame.size.width)];
        } else if (self.useSmartBanner) {
            self.gadView = [[GADBannerView alloc] initWithAdSize:kGADAdSizeSmartBannerPortrait];
        } else {
            self.gadView = [[GADBannerView alloc] initWithAdSize:kGADAdSizeBanner];
        }
        self.gadView.adUnitID = GAD_TEST_MODE ? GAD_TEST_UNIT_ID : GAD_UNIT_ID;
        self.gadView.delegate = self;
        [self loadAdMobBanner:targetView];
    }

    if (![self.gadView.superview isEqual:targetView]) {
        [self.gadView removeFromSuperview];
        [self loadAdMobBanner:targetView];
    }
}

- (void)loadAdMobBanner:(UIView *)view
{
    self.gadView.rootViewController = self.currentRootViewController;

    CGRect gadViewFrame = self.gadView.frame;
    gadViewFrame.origin = CGPointMake(bannerX, bannerY);
    self.gadView.frame = gadViewFrame;
    [view addSubview:self.gadView];

    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(@"DCAdMobBanner -> usePersonalizedAds: %d", self.usePersonalizedAds);

    [self.gadView loadRequest:request];
}

#pragma mark - delegate method

- (void)adViewDidReceiveAd:(GADBannerView *)bannerView
{
    BOOL const useFadeInAnimation = self.fadeInDuration > 0.0;
    if (useFadeInAnimation) {
        bannerView.alpha = 0.0;
        [UIView animateWithDuration:self.fadeInDuration animations:^{
            bannerView.alpha = 1.0;
        }];
    }

    _loaded = YES;

    isFailed = !_loaded;
}
- (void)adView:(GADBannerView *)bannerView didFailToReceiveAdWithError:(GADRequestError *)error
{
    _loaded = NO;

    isFailed = !_loaded;

    // バナー再読み込み
    [self showAdBanner:self.currentRootViewController yPos:bannerY fadeInDuration:self.fadeInDuration
     useAdaptiveBanner:self.useAdaptiveBanner useSmartBanner:self.useSmartBanner usePersonalizedAds:self.usePersonalizedAds];
}

- (void)adViewWillPresentScreen:(GADBannerView *)bannerView
{
}

- (void)adViewDidDismissScreen:(GADBannerView *)bannerView
{
}

- (void)adViewWillDismissScreen:(GADBannerView *)bannerView
{
}

- (void)adViewWillLeaveApplication:(GADBannerView *)bannerView
{
}

@end

関連記事

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)