読者です 読者をやめる 読者になる 読者になる

24/7 twenty-four seven

iOS/OS X application programing topics.

NSTimer を使うアプリ(時計、ゲームなど)で Mobclix 広告を利用する場合の注意点

iPhone Objective-C Cocoa

実は審査中の「カラー・ペアーズ」[YouTube]も思いがけないバグを提出後に発見した為、一度自分でリジェクトして提出し直しました。
そのバグとはプレイ中に表示していたmobclix広告から発生するものでした。
どういうバグかというと、このゲームは60秒からカウントダウンが始まり、ゼロになったら終了という流れなのですが、どういうワケかmobclixの広告を押しっぱなしの状態で指を離さずにいると、カウントが止まったまま動かなくなるというものです。
タイムを止めた状態でもゲームは続けられるため、広告の上に指を置いた状態を保てば、無限にスコアを伸ばせるという非常に厄介なバグです。これではどんなに楽しいゲームも一気に冷めます。

http://studioloupe.wordpress.com/2010/01/12/bug/

上記の問題について、思い当たることがあったので少し調べてみました。


不具合は NSTimer のコールバックが発火しないということだろうと思ったので、下記の記事で書いた、スクロール中は NSTimer がストップしてしまう現象だと推測しました。

スクロール(ドラッグ)中でもタイマーを止めない方法 - 24/7 twenty-four seven


で、 Mobclix に登録して、 SDK とサンプルを見てみると、どうも Mobclix の広告バナーを表示するためのビューは UIWebView を継承しているようです。
UIWebView はスクロール機構を持っているので、広告バナーを押しっぱなしの状態というのは、厳密には押しっぱなしというか、少し指が動いてしまって、スクロールが発生している状態になってしまうんじゃないかなと思いました。


そんなところをコメントしたところ、だいたい合っていたようなので、よかったです。

それと今朝、「世にも奇妙なバグ」で書いたバグについて、LCD Clock, MyWebClip, やJapan Subway Route Map などのプログラムを手がけた岸川克己さんからご指摘いただき、無事問題が解決できました!

http://studioloupe.wordpress.com/2010/01/17/confession/


いちおうその後もちょこちょこと調べたので分かったことをまとめておきます。

Mobclix の広告ビューは UIWebView を継承している
- (void) adViewDidFinishLoad:(MobclixAdView *) adView{
    NSLog(@"%@", [[adView superclass] superclass]);
2010-01-17 23:12:09.131 MobclixDemo[73633:207] UIWebView
UIScrollVIew, UITextView, UITableVIew, UIWebVIew のスクロールは NSTimer を止める

UITextView, UITableVIew は UIScrollVIew の派生クラスなので当然、UIWebVIew のスクロールも NSTimer を止めます。


解決策は、前に書いたように、モードを NSRunLoopCommonModes に指定して Run Loop に登録します。

NSTimer *timer = [NSTimer timerWithTimeInterval:1.0f target:self selector:@selector(onUpdate:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];


あまり、スクロールビューやテーブルビューとタイマーを併用するようなアプリは無いので普通は気にすることはありませんが、時計、ゲームで広告を表示するというアプリはよくあるパターンと思いますので、そういうことにも注意したほうがいいのかもしれません。