2016年6月27日月曜日

GoogleのAdMobを組み込む

iAdが廃止になるし、サードパーティ製の広告サービスの組み込みが必須になった。

広告サービスの種類はよく知らないので、GoogleのAdMobというのをとりあえず組み込んでる。
iAd同様にバナー広告を表示してくれるのでわかりやすいし、はやりのインターステーシャル広告とかなんとかにも対応してる。

難点は、リリース済みのアプリじゃないといけない点だ。iAdみたいにSDKを組み込むだけでなく、AdMobの管理サイトでアプリを認識させないといけないため、リリース済みであることが必要になるのだな。
アップルのAppStoreの情報をGoogleが参照してるってのも変な話だが。
リリース前のアプリにも組み込めるのかもしれないが、そちらはわかり次第追記したい。

とりあえず簡単にやり方をまとめる。

概要

やることは以下のように単純。
  • AdMobのFrameworkをプロジェクトにインポートする
  • クラスの先頭で import GoogleMobileAds する
  • StoryboardもしくはコードからGADBannerViewクラスのオブジェクトを作って表示させる
Firebaseというモバイルサービスプラットフォームの一部なのだそうだが、説明が英語なのでよくわかってない。
とりあえずFirebaseを設定しなくても広告は表示できるようなので、わかったら追記したい。

必要条件

  • Xcode 7.0以上
  • iOS 7.0以上
  • Firebaseプロジェクトが有効なこと
  • 管理を簡単にするため、CocoaPodsのインストールを推奨

手順

AdMobのアカウントを作成

AdMobのサイトでアカウントを作成する。
細かいやり方は略す。

アプリを追加

  • 新しいアプリの収益化
    • AppStoreにリリース済みのアプリを、アプリ名や開発者名で検索して選択
  • 広告フォーマットを選択
    • 通常のバナー広告(画面隅に出しとくアレ)
    • インターステーシャル広告(アプリの場面切り替え時などに表示する全面広告)
    • ネイティブ広告(デバイスに最適な広告を表示してくれるらしいが、まだよくわからん)
    • ……などを選ぶ
  • Firebaseアナリティクスの設定
    • 新しい広告向けのアクセス解析サービスだが、設定方法がまだよくわからん
  • SDKのインストール
    • 詳細は以下に

SDKのインストール

「表示の設定方法」にリンクされてるGoogle Mobile Ads SDKのページで googlemobileadssdkios.zip ってのをダウンロード。

次にXcodeにインストールするのだが…
以前は日本語でとってもやさしく説明してくれてたページ(この辺?)があったんだけど、現バージョンについてはFirebaseの英語ページしか出てこん!? 探す!
とりあえずこちらのページを参考にする。

以前のバージョンではiOSのAdSupportとかAVFoundationとかCoreMediaとか、11個ものFrameworkをインストールする必要があったが、最新版ではインストール不要になったようだ。

必ずコピーすること
Xcodeの左側のファイルインスペクタからアプリ名を右クリックして、Add Files to "アプリ名"...を選び、ダイアログから、ダウンロードしたAdMobSDKのフォルダの中のGoogleMobileAds.frameworkをインストールする。
この際、ダイアログ下にあるOptionsボタンを押し、Copy items if neededをチェックすること。そうしないとframeworkへのリンクが貼られるだけとなるため、frameworkのファイルを移動したり捨てたりすると機能しなくなっちゃう。

とりあえずしなくてもいいこと?

GoogleService-Info.plistを入手

正式にはアプリに関する構成情報を格納するGoogleService-Info.plistというファイルを使用するそうである。
入手するにはFirebase consoleにログインしてアプリを登録するか、もしくはサンプルの同.plistファイルをダウンロードし、プロジェクトと同じディレクトリーに保存するのだそうだ。
重要:GoogleService-Info.plistファイルは広告のUnit IDを保存しません。あなたは他の手段で広告のUnit IDを格納、読み出さなければなりません。 
しかし、Firebaseの方も英語の説明しかないので、よくわからない。
とりあえずFirebaseとか.plistファイルとかを考えなくても広告は表示できるようなので、無視しておこう。

Podfileを作る

プロジェクトと同じディレクトリに、以下の内容を含むPodfileというファイルを作れとある。
source 'https://github.com/CocoaPods/Specs.git'

platform :ios, '7.0'

target 'BannerExample' do
  pod 'Firebase/Core'
  pod 'Firebase/AdMob'
end

pod installの実行

ターミナルから同じディレクトリのpod installを実行してください。
インストールが終わったらプロジェクトを閉じ、プロジェクト名.xcworkspaceを開いてください。
あなたのプロジェクトファイルはFirebaseとAdMobのために新しいPodsプロジェクトを含まねばなりません。
…とあるんだが、これも無視してもできたようだ。

コードからGADBannerViewを参照する

こっからはまたちゃんと作業すること。

広告を表示するViewControllerの先頭でGoogleMobileAdsをimportする。

  • Swiftの場合
    • import GoogleMobileAds
  • Objective-Cの場合
    • #import <GoogleMobileAds/GoogleMobileAds.h>

StoryboardでAdMobのUIViewを貼る方法と、コードから作る方法と2通りあるのはiOSの他の部品と一緒だ。
Storyboardで貼るなら、UIViewをドラッグして配置し、カスタムクラスを GADBannerView に設定する。Outletも引っ張って変数を作っとくこと。

広告をGADBannerViewに読み込む

最後に、バナー広告を表示させるViewControllerにコードを加えよう。

Storyboardで作った場合

override func viewDidLoad() {
  super.viewDidLoad()

  print("Google Mobile Ads SDK version: " + GADRequest.sdkVersion())
  adMobBanner.adUnitID = "ca-app-pub-xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  adMobBanner.rootViewController = self
  adMobBanner.loadRequest(GADRequest())
}

コードから作る場合

上記コードを以下のように置き換える。
//いくつかサイズがあるが、スマートバナーにしておけば画面横幅に(だいたい)合わせてくれる
adMobBanner = GADBannerView(adSize: kGADAdSizeSmartBannerPortrait)
//広告ユニットIDを指定。AdMob設定時に書かれてたもの
adMobBanner.adUnitID = "ca-app-pub-xxxxxxxxxxxxxxxxxxxxxxxxxx"
//ルートのViewControllerを指定。だいたい self でいいのでは。
adMobBanner.rootViewController = self;
//バナーの位置を画面サイズと自分の大きさから決定(画面下に貼る場合)
adMobBanner.frame = CGRectMake(CGRectGetMidX(view.frame) - adMobBanner.frame.size.width / 2, CGRectGetMaxY(view.frame) - adMobBanner.frame.size.height, adMobBanner.frame.size.width, adMobBanner.frame.size.height) //中央に配置
//viewに追加
view.addSubview(adMobBanner)
adMobBanner.delegate = self //Delegateの設定
//広告を読み込んで表示させる
adMobBanner.loadRequest(GADRequest())

上記コードの3カ所を変更してください。
1、上記コード中のadUnitID(xxxxxxxxxxxxxxxxxxxxxxの部分)を、AdMob設定時に表示された自分のUnitIDに置き換える。
本物の広告をタップして、違反としてアカウント停止にならないよう、テスト用UnitIDがあるというんだけど、どれだよ?

2、バナーを表示するためのルートのViewControllerを指定する。
このViewControllerは広告がクリックされたときに重ねて表示される際に使われる。
とりあえず self でいんじゃね?

3、GADBannerViewのloadRequest関数をGADRequest()オブジェクトでコール。
これで広告が読み込まれ、表示される。

Delegateの設定

iAd同様、広告が表示できたりできなかったりの時に呼ばれるDelegate関数がいくつかある。

当然、クラス先頭でDelegateの宣言をする。
class ViewController: UIViewController, GADBannerViewDelegate { … }

関数名はadView〜で始まるので、入力すると補完表示してくれるのでそれで調べて。

//Delegate関数
    func adViewDidReceiveAd(bannerView: GADBannerView!) {
        print("AdMob表示できた😄")
    }
    
    func adView(bannerView: GADBannerView!, didFailToReceiveAdWithError error: GADRequestError!) {
        print("AdMob表示できず🤔\(error)")
    }

didFailToReceiveAdWithErrorの方は表示失敗時だと思うんだが、表示失敗しなくても(この関数が呼ばれなくても)広告が表示されない場合があるようだ。この辺はよくわからん。

テスト用広告の設定

開発中に、誤タップや表示回数の統計に影響しないよう、本物の広告のかわりにテスト用広告を表示するように指示されている。
そのためにiOSシミュレータもしくは実機のテストデバイスIDを設定する必要がある。

シミュレータはすでにAdMobの方で定数kGADSimulatorIDとして宣言されてるのでそれを使う。

実機の方はデバイスごとに違うので、一度実機でAdMobを表示させた場合、Xcodeの下部のメッセージ欄に表示される以下のようなメッセージの「xxxxxxxxxxxxxxxxxxxxxxxxxxx」の部分を使う。
2016-06-28 00:29:04.837 alien[8831:7496717] <Google> To get test ads on this device, call: request.testDevices = @[ @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ];

前述したコードの
//広告を読み込んで表示させる
adMobBanner.loadRequest(GADRequest())
の部分を以下に置き換えればいい。

//テスト広告表示用
let request:GADRequest = GADRequest()
if TARGET_OS_SIMULATOR == 1 {
      request.testDevices = [kGADSimulatorID] //iOSシミュレータ用
} else {
      request.testDevices = ["xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"] //実機用
       }
//広告を読み込んで表示

adMobBanner.loadRequest(request)

要はGADRequestクラスのプロパティを変更し、loadRequestしているわけだ。
シミュレータと実機のどっちで実行されてるのかは TARGET_OS_SIMULATOR で判定できる。
(1がシミュレータ、0が実機)
値はXcodeでシミュレータと実機のどちらを選択しているかで変化するので、Will never executedというWarningが出るけど気にしないでいい。

リリース時はこのままのコードでかまわない。
なぜなら、テストデバイスIDが実行デバイスと異なる場合には本物の広告が表示される仕組みだからだ。

Objective-Cの場合のコード

Objective-Cで書く場合も参考までにざっと載せとく。
- (void)adMob
{
    //いくつかサイズがあるが、スマートバナーにしておけば画面横幅に(だいたい)合わせてくれる
    adMobBanner = [[GADBannerView alloc]initWithAdSize:kGADAdSizeSmartBannerPortrait];
    //広告ユニットIDを指定する
    adMobBanner.adUnitID = @"ca-app-pub-**********************"; //WebAdMobの広告設定時に書かれてたもの
    adMobBanner.rootViewController = self;
    adMobBanner.frame = CGRectMake(CGRectGetMidX(self.view.frame) - adMobBanner.frame.size.width / 2, 0.0,
                                    adMobBanner.frame.size.width, adMobBanner.frame.size.height); //中央に配置
    [self.view addSubview:adMobBanner];
    //広告を読み込んで表示
    GADRequest *request = [GADRequest request];
    //テスト広告の設定
    if (TARGET_OS_SIMULATOR == 1) {
        request.testDevices = @[kGADSimulatorID]; //iOSシミュレータ用
    } else {
        request.testDevices = @[@"******************************"]; //実機用
    }
    [adMobBanner loadRequest:request];
}

変なメッセージが出る

うちでは出なかったんだけど、以下の変なメッセージが出る場合があるようだ。
This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes.  This will cause an exception in a future release.
「バックグラウンドのスレッドでオートレイアウトをいじってるようだな? 将来痛い目にあうぞ!」という内容だと思う。
どうやらViewが確定する前のviewDidLoadメソッドとかでAdMobを初期設定したりすると出るようで。
以下のようにdispatch_asyncのブロック中に入れておけば大丈夫だそうだ。(以下はObjective-Cのコード)
dispatch_async(dispatch_get_main_queue(), ^{
        ここにadMob設定コードを書く

    });

審査提出時の注意

AdMobはターゲット広告を利用するようなので、iTunesConnectから審査提出時に最後に聞かれる「IDFAを使ってるかどうか」などという項目に必ずチェックを入れること。
IDFA使ってるのにチェックを入れないと、リジェクトされて新しいバイナリを求められるってさ。
「下記の目的で…」のチェックは自分の場合、一番上の「App内で広告を出す」だけで良かったみたい。他の項目は何言ってるのかわかんないしねw

0 件のコメント:

コメントを投稿