cordova-plugin-admob-freeでInterstital not ready yetエラー

最近(2018年10月)、Ionic3でAndroidアプリを作って、Play Storeで公開しました。

そこに至るにはいろいろと罠がありましたので、その記録を思い出せるうちに書いて残しておこうと思います。

困ったり解決したりする度に[ツイートしてた](https://twitter.com/agajo_tech)からいけるはず……！！

いくつかの記事にわけて、シリーズとしてまとめておきます。

なお、なんとかリリースできたアプリはこちら。日本語入力速度を測定します。→[フリックとローマジ 〜日本語入力スピード測定〜](https://play.google.com/store/apps/details?id=oka_ryunoske.work.flickromaji.app)

#シリーズ一覧

 - [小さめの奴をまとめて](https://qiita.com/agajo/items/dee6c5c994fe0e5ef001)
    - Ionicアプリにおける、色の指定のしかた
    - アプリのIDを初期値にしたまま端末に複数インストールすると上書きされる
    - iconとsplashの生成
    - android実機デバッグでエラーメッセージを見る
    - chromeでinspectタブを開いていると、端末ビルド時にno device error
    - play-services-ads v17 でAndroidManifest.xmlのmeta-data強制
 - [複数のファイルにまたがるPromiseの使い方](https://qiita.com/agajo/items/c466a4cdc3930dd43206)
    - IonicのNavControllerはProviderからは使えない
 - [プライバシーポリシー](https://qiita.com/agajo/items/e886afb7f5408141d1fc)
 - admob-freeプラグインでのeventsオブジェクトの扱い(この記事)
 - [firebaseプラグイン導入時のGoogle Play Services libraryのバージョン調整](https://qiita.com/agajo/items/8106eb0883d2d3c82add)
 - [Lazy Loading への対応](https://qiita.com/agajo/items/f13a2ae06c70fef8887b)
    - ngIf、ngForが動かない時

#cordova-plugin-admob-free

2018年10月15日現在、Ionicで使えるCordovaプラグインのうち、AdMobを導入するためのものは２つあって、片方はお金を払わないと収益の一部を持っていかれるようです(恐らく正確には、広告インプレッションの一部を持っていかれる)

で、そういうことがなく、完全無料を謳っているのがこちらのcordova-plugin-admob-freeです。

https://ionicframework.com/docs/native/admob-free/

https://github.com/ratson/cordova-plugin-admob-free

これの使い方で一部困った症状があったので、その症状と対策を紹介します。

#症状

こことほぼ同様です。

https://github.com/ratson/cordova-plugin-admob-free/issues/118

要約すると、

Interstitial広告を、きちんと`prepare().then(()=>show())`という形で、prepareの完了を待ってから表示するようにしているのに、

なぜか`Uncaught (in promise): Interstital not ready yet`というエラーが出る

というものです。

バナー広告ならこの書き方で問題なかったのに。

こちら、原因は結局よくわかりませんでしたが、どうも、

この書き方をしているにもかかわらず、きちんと準備完了を待ってくれていないようです。

その証拠に、上記リンクを読んでみると、「prepareを実行してから物理的に2秒待ってshowするとうまくいく」という記述があります。

ですがまあ、その方法だと、2秒以内に読み込んだ時も2秒待っちゃうし、2秒で読み込めなかったら相変わらずエラーだし、ちょっとまずいですね。

ちゃんと、順序正しく実行するように書いてみましょう。

#対策

そこで、Promiseのthenに頼るのをやめて、「準備完了イベントをトリガーに、表示処理を動かす」という方針で実装したらうまくいきました。

が。

イベントまわりのコーディングをどんな感じでやったらいいのかが全然説明されておらず、やや苦労しましたので、最終的にどうしたかを紹介します。

コードはこんな感じ。

```typescript
...
  constructor(..., private admobFree: AdMobFree, ...) { }
...
      admobFree.interstitial.prepare();//prepareは単体で実行
      //以下、各イベントに対する応答を登録しておく
      admobFree.on(admobFree.events.INTERSTITIAL_LOAD).subscribe(()=>{
        admobFree.interstitial.show();//広告表示
      });
      admobFree.on(admobFree.events.INTERSTITIAL_LOAD_FAIL).subscribe(()=>{
        インタースティシャルがロードできなかった時の処理;
      });
      admobFree.on(admobFree.events.INTERSTITIAL_CLOSE).subscribe(()=>{
        インタースティシャル広告を閉じた時の処理;
      });
```

解説していきます。

##admobFree.on().subscribe

admobFreeのonメソッドは、Observableを返します。Observableとは、RxJSライブラリを読み込むと使えるようになる、Promiseみたいなものです。IonicやAngularでは必須となっています。

Promiseの場合は`.then`にその後の処理を書きますが、Observableの場合は`.subscribe`の中にその後の処理を書きます。

今回は、「広告のロード完了時」「広告のロード失敗時」「広告を閉じた時」の３つのタイミングで処理を登録しておきたいので、３つ書いてあります。

別にこの順に実行されるとかいうわけではないです。各イベントに対する応答を登録しておくイメージ。

##イベントの名前

実は一番困ったのがここです。

創出されるイベントの一覧はどこにあるの？？？ということ。

で、ここにあるのを見つけました。

https://github.com/ionic-team/ionic-native/blob/master/src/%40ionic-native/plugins/admob-free/index.ts

はい。完全にソースコードです。時には見なきゃいけないですね〜〜〜。

ここの124行目から書いてあります。(2018年10月15日現在)

ここを参考にイベントの名前を突き止めれば、

```typescript
admobFree.on(admobFree.events.INTERSTITIAL_LOAD).subscribe(()=>{
  admobFree.interstitial.show();
});
```

みたいに書けますね。これでOKです。





ということで、この記事は以上です。

結局、なんで`prepare().then(()=>show())`という形では駄目なんでしょうね…。