iAdの表示処理をCCLayerに乗せて汎用性を高める

| コメント(0) | トラックバック(0)
こんにちは。開発担当のICTFです。

iAd(広告)をアプリに組み込む場合、通常は複数の画面にわたって実装しますよね。
さらにiAdの表示を行なう為にはcocos2dフレームワーク外の仕組みを使わねばなりません。
cocos2dフレームワーク外という事は、ある画面でiAdを表示している状態で次の画面に遷移した場合、フレームワーク外のiAdはそのまま残ってしまうという事です。
ある意味画面をまたいで表示し続けられるのは利点とも受け取れますが、iAdを表示したくないメインゲーム画面などに残ってしまい、大切なパラメータが隠されてしまうという不具合の原因にもなり得ます。
そこで今回は1つのCCLayerにiAdの表示から消去までの仕組みをすべて乗せてしまいたいと思います。(以下iAdLayerと呼びます)
使い方のイメージは、iAdを表示したい画面でiAdLayerをaddChildするだけです。
iAdの消去はiAdLayerが解放されるタイミングで自動的に行なわれます。

[iAdLayer.h]

// iAd表示用のレイヤ

@interface iAdLayer : CCLayer 

<ADBannerViewDelegate>

{

    ADBannerView* m_AdView;

}


@property (nonatomic, retain) ADBannerView* AdView;


@end


ヘッダファイルにはiAdを表示する為のビュークラスを追加します。

またコールバックを受け取るため、ADBannerViewDelegateプロトコルを実装する必要があります。


[iAdLayer.m]

-(id) init

{

if (self = [super init]) {

// 通知センタのオブザーバ登録

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(NotifyFromNotificationCenter:) 

name:nil object:nil];

m_AdView = nil;

m_prevOrientMode = eOrientationMode_Full;

[self createIAd];

}

return self;

}


-(void) dealloc

{

// 通知センタのオブザーバ登録を削除する

[[NSNotificationCenter defaultCenter] removeObserver:self];

[self releaseIAd];

[super dealloc];

}


init中でiAdの生成処理「createIAd」をコールし、dealloc中でiAdの解放処理「releaseIAd」をコールしています。

後はこの2つのメソッドを実装すれば、iAdLayerを貼付けるだけで広告の実装完了という仕組みを実現できます。


// 広告ビューの生成

-(void) createIAd

{

// 広告ビューが生成済みの場合、一度解放する

[self releaseIAd];

RootViewController* rootVC = [CommonFunctions getRootViewController];

// 広告ビューを初期化

self.AdView = [[ADBannerView alloc] initWithFrame:CGRectZero];

self.AdView.delegate = self;

self.isBannerVisible = YES;

UIInterfaceOrientation orientation = rootVC.interfaceOrientation;

float h = 0;

if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {

self.AdView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;

h = rootVC.view.frame.size.height;

}

else {

self.AdView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierLandscape;

h = rootVC.view.frame.size.width;

}

// 画面の下部に表示

self.AdView.frame = CGRectOffset(m_AdView.frame, 0, h - m_AdView.frame.size.height);

[[[CCDirector sharedDirector] openGLView] addSubview:m_AdView];

}


// 広告ビューの解放

-(void) releaseIAd

{

if (m_AdView != nil) {

[m_AdView removeFromSuperview];

[m_AdView release];

self.AdView = nil;

}

}


createIAd内で紹介していないメソッドなどが登場しますが、これはデバイスの向きを調べ、それに合わせた広告の配置を行なう為のものです。

また、前述のinit内で通知センタへの登録を行なっていますが、これはデバイスの向きが変わった事を知る為の登録です。


// 通知センタからの通知イベント

-(void) NotifyFromNotificationCenter:(NSNotification*)notification

{

if (notification.object == nil) {

return;

}

if (notification.name == ROOTVIEWCONTROLLER_NOTIFY_MSG_ROTATE) {

// 画面回転通知

// 広告ビューの再生成

[self createIAd];

}

}


rootViewController内でデバイスの向きが変わった事を検知し、
ROOTVIEWCONTROLLER_NOTIFY_MSG_ROTATEメッセージを発行しています。

iAdLayerでそのメッセージを受け取った時に広告ビューを再生成する事で動的なデバイス回転に対応できるようになります。


少し1つの機能をCCLayerに盛り込むと汎用性が高くなるという話題から逸れてしまいましたが、CCLayerはとても便利なクラスです。何も目に見えるもの以外は実装に向いていない訳ではないと思います。


例えばDBにアクセスする為、色々な画面で用いられるSQL文(ユーザ認証当たりが該当するのではないでしょうか)の発行から処理までの一連の流れをCCLayerに実装し、使いたい場面でそのレイヤを貼付けるというのはどうでしょうか?

貼付けたタイミングでSQLが発行され、処理が終了したタイミングで自動的にremoveFromParentAndCleanupされる訳です。


1つ注意点として、CCLayerのフレームワークに従うという事は、シーンが変わるとレイヤが解放される事は基本的に避けられないという事です。

重要な処理を乗せたレイヤを動かしている場合、画面遷移をブロックする処理が必要となるでしょう。

これは今回の話に限りませんね。

トラックバック(0)

トラックバックURL: http://www.ict-fractal.com/MovableType/mt/mt-tb.cgi/11

コメントする

Twitterボタン
Twitterブログパーツ