MILLEN BOX

音楽好きの元組み込みソフトエンジニアによるプログラミング(主にiOSアプリ開発)の勉強の記録

SwiftでAdMobバーナー広告を表示する [swift1.2] [AdMob] [GoogleMobileAds]

私、一度アプリをリリースしており、その際にAdMobバーナー広告の表示に対応しております。

初アプリ!RPNConverterをリリースしました! - MILLEN BOX

アプリが形になったきた!その後にやったことのメモ [はじめてのアプリ申請] - MILLEN BOX

前回はスムーズに実装できましたが、現在作成しているアプリへ同様の対応を行ったところ、見事にハマってしましました。
結構同じようなところでハマっている人も多いのでは?と思い、2015年9月7日時点の情報として、記録を残しておこうと思います。
因みに今回は、実際のアプリリリースの際に必要なAdMobバーナー表示用のID登録といった作業については割愛しています。(IDを登録しなくてもシミュレーターにてテスト用広告が表示可能なため、実装を行う上で問題はありません。)

f:id:anthrgrnwrld:20150907190049p:plain

Githubは以下です。

github.com

手順1

以下のリンクからGoogle Mobile Ads SDKをダウンロードする。2015年9月7日時点では最新版のVerはv7.4.1です。

Google Mobile Ads SDK  |  AdMob for iOS  |  Google Developers

手順2

ダウンロードした GoogleMobileAdsSdkiOS-7.4.1フォルダ 全てをプロジェクトに追加するのですが、その際に気をつけるポイントが。
フォルダをそのままドロップしてプロジェクトに追加するのではなく、Xcode内Navigator + 右クリック → Add File to "(Project名)" を使用して追加した方が妥当ということです。
私の場合の話ですが、ドロップして追加した場合には、最終的に必要なファイルがない!と怒られることがありました。
しかし、その後ドロップにて追加したファイルを削除し、Xcode内Navigator + 右クリック → Add File to "(Project名)" の方法で追加し直すと、上手くいきました。
確証はありませんが、今回オススメした追加方法の方が無難です。
f:id:anthrgrnwrld:20150907080017p:plain

手順3

Project -> TARGET -> General -> Linked Frameworks and Libraries にて、AdMob実装に必要なframeworkを追加します。
以下が追加必要なframeworkです。(GoogleMobileAds.frameworkは手順2にて自動的に追加されます。)

  • AdSupport
  • AudioToolbox
  • AVFoundation
  • CoreGraphics
  • CoreTelephony
  • EventKit
  • EventKitUI
  • MessageUI
  • StoreKit
  • SystemConfiguration

f:id:anthrgrnwrld:20150907191121p:plain

手順4

AdMob-Bridging-Header.h を新規作成します。Xcode左下の+ボタンから追加して下さい。
このヘッダーファイルは、Objective Cで書かれたAdMob SDKを、swiftで使用するための中間ファイルと考えて結構です。
そしてファイルを開き、#define AdmobTest_AdMob_Bridging_Header_h#endifの間に、#import "GoogleMobileAds/GoogleMobileAds.h"#import "GoogleMobileAds/GADInterstitial.h"を追加して下さい。

#ifndef AdmobTest_AdMob_Bridging_Header_h
#define AdmobTest_AdMob_Bridging_Header_h

#import "GoogleMobileAds/GoogleMobileAds.h"  //追加
#import "GoogleMobileAds/GADInterstitial.h"  //追加

#endif

ここでまた注意事項です。
ネットで上がっている記事では、、ヘッダーファイルの中身を、#import "GADBannerView.h"#import "GADInterstitial.h"としている場合がありました。しかしこの記載では、少なくとも私の環境ではビルドを通すことが出来ませんでした。
恐らくこの方法は、現時点(2015/09/07)では、使用出来ないのでは と感じています。

手順5

Project -> TARGET -> Build Settings -> Swift Compiler – Code Generation -> Objective-C Bridging Headerにて、手順4で追加したheaderファイルパスを追加します。
具体的には アプリマーク + Project名 の列に、$(SRCROOT)/$(PROJECT)/AdMob-Bridging-Header.hを追加します。

f:id:anthrgrnwrld:20150907195026p:plain

手順6

Project -> TARGET -> BuildSettings -> Linking -> Other Linker Flags にて、Linker Flagを追加します。
具体的には アプリマーク + Project名 の列に、-ObjCを追加します。

f:id:anthrgrnwrld:20150907195615p:plain

手順7

バーナー広告を表示するプログラムを作成します。
viewDidLoadでGADBannerViewのインスタンスをaddSubviewすることで表示しています。
getAdBannerViewは表示位置調整などを行う関数で、他に「シミュレーター用」、「実機(テスト)用」、「本リリース用」でIDを切り替えれるようにしています。
因みに、以下で記載したIDを使用すれば、本IDが無くてもシミュレーター上で問題なくバーナー表示がされます。

import UIKit

class ViewController: UIViewController, GADBannerViewDelegate {
    
    let YOUR_ID = "ca-app-pub-3530000000000000/0123456789"  // Enter Ad's ID here
    let TEST_DEVICE_ID = "61b0154xxxxxxxxxxxxxxxxxxxxxxxe0" // Enter Test ID here
    let AdMobTest:Bool = true
    let SimulatorTest:Bool = true

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        let bannerView:GADBannerView = getAdBannerView()
        self.view.addSubview(bannerView)
        
    }
    
    private func getAdBannerView() -> GADBannerView {
        var bannerView: GADBannerView = GADBannerView()
        bannerView = GADBannerView(adSize:kGADAdSizeBanner)
        bannerView.frame.origin = CGPointMake(0, 20)
        bannerView.frame.size = CGSizeMake(self.view.frame.width, bannerView.frame.height)
        bannerView.adUnitID = "\(YOUR_ID)"
        bannerView.delegate = self
        bannerView.rootViewController = self
        
        var request:GADRequest = GADRequest()
        
        if AdMobTest {
            if SimulatorTest {
                request.testDevices = [kGADSimulatorID]
            } else {
                request.testDevices = [TEST_DEVICE_ID]
            }
        }
        
        bannerView.loadRequest(request)
        
        return bannerView
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

手順8

Project -> TARGET -> Build Settings -> Search Paths – Framework Search Paths にて、 参照するframeworkにGoogleMobileAdsSDKが入っていることを確認して下さい。
入っていない場合には$(PROJECT_DIR)/GoogleMobileAdsSdkiOS-7.4.1などを各自の環境に合わせて追加して下さい。
正確に参照できていないとブリッジヘッダーの読み込み時にエラーになります。
f:id:anthrgrnwrld:20150908123711p:plain

手順9

ビルドを行いエラーが発生しないか確認して下さい。
手順8までを間違いなくできていれば、ビルドが通り、問題なくバーナーが表示されるはずです。
ビルドが通り、バーナーが表示された方はここで終了です。
しかし、ある事をしていた場合、エラーとなりここまでの手順のみではビルドが通らない という事態になります。
私は今回、この部分にガッツリハマってしましました。
ある事 とは?それは手順10を参照下さい。

手順10

XCTestを使用することを前提とした場合、手順8までのみの手順だと問題が発生します。
よくよくエラーを見れば、テスト用ファイルでビルドエラーが発生していることに気付くはずです。ただ、人間って思い込みで全然検討違いのことを疑ったりするんですよねー(遠い目)
f:id:anthrgrnwrld:20150908124048p:plain

ViewController.swiftなどのファイル選択 -> Utilities Area -> Target Membership にて(Project名)Testsにチェックが入っているかを確認して下さい。チェックが入っている場合、XCTestを使用すること設定になっています。

手順11

エラー回避方法として行うこと、その一つ目は、単体テスト用ファイル(Project名)Tests.swiftに対し、手順5手順6手順8の作業を行うことです。
あ、この作業が終わってもまだエラーが取りきれないと思いますが、焦らないで下さい。

手順5 '
f:id:anthrgrnwrld:20150908182733p:plain

手順6 '
f:id:anthrgrnwrld:20150908182846p:plain

手順8 '
f:id:anthrgrnwrld:20150908182909p:plain

手順12

手順11まで完了しても、Mach-O Linker Error が発生するためビルドが通りません。

f:id:anthrgrnwrld:20150908183208p:plain

このエラーの解決の為、単体テスト用ファイル(Project名)Tests.swiftProject -> TARGET -> Link Binary Libraries にて、手順3で追加したframeworkGoogleMobileAds.framework を追加して下さい。
f:id:anthrgrnwrld:20150908183946p:plain

手順13

ビルドを行いエラーが発生しないか確認して下さい。
ビルドが通り、バーナーが表示された場合は終了です。ビルドがまだ通らない方はもう一度初めから見なおして下さい。
もしどうしてもエラーが消えない場合、小さいテスト用プロジェクトを新規で作成して、はじめのはじめからやり直すのもアリと思います。