2017年9月2日土曜日

SpriteKit に Firebase/Admob を導入してみた

概要

SpriteKit で開発したゲームに Firebase/Admob を導入してみました
今回は GADBannerView でバナー広告を表示するのではなく全画面に表示される Interstitial Ads を導入してみました

環境

  • macOS X 10.12.6
  • Xcode 8.3.3 (8E3004b)
  • Firebase 4.0.2
  • Google-Mobile-Ads-SDK 7.20.0

ライブラリインストール

  • pod init
  • vim Podfile
pod 'Firebase/Core'
pod 'Firebase/AdMob'
  • pod install

.xcworkspace を開きます
ついでに GoogleService-Info.plist をプロジェクトにコピーしておきましょう

AppDelete.swift で初期化

これはいつも通りです

import Firebase

でインポートして didFinishLaunchingWithOptions で初期化します

FirebaseApp.configure()

GameViewController.swift で広告を生成

まず UIViewController 側で広告の初期化や生成を行うメソッドを準備します

import GoogleMobileAds

でインポートします
GameViewController に GADInterstitialDelegate を継承しましょう

class GameViewController: UIViewController, GADInterstitialDelegate {
    ...
}

そしてインタースティシャル広告用の変数を定義します

var interstitial: GADInterstitial!

Interstitial Ad を初期化

次に interstitial を初期化する関数を定義します

// Interstitial Ad を作成します
func createAndLoadInterstitial() -> GADInterstitial {
    let interstitial = GADInterstitial(adUnitID: "ca-app-pub-3940256099942544/4411468910")
    interstitial.delegate = self
    let request = GADRequest()
    request.testDevices = [ kGADSimulatorID ];
    interstitial.load(request)
    return interstitial
}

ここは特に説明する必要はないと思います
継承した GADInterstitialDelegate を interstitial.delegate に設定しましょう

広告を表示する関数を追加

次に広告を表示する関数です

// 広告を表示します
func showAd() {
    if interstitial.isReady {
        print("showAd")
        interstitial.present(fromRootViewController: self)
    } else {
        print("Ad wasn't ready")
    }
}

print 分はデバッグなので削除して OK です
この広告の呼出し方法も決まり文句みたいなものなのでほぼそのまま使えば OK です

広告が非表示になったコールされる関数を定義

インタースティシャル広告の場合画面全体に広告が表示されます
Admob の場合閉じるボタンも勝手に生成してくれます
ただ、インタースティシャル広告は一度表示したら再度生成しなおす必要があります
なので、広告が非表示になったタイミングで再度生成します

// 広告が非表示になった場合に再度生成します
func interstitialDidDismissScreen(_ ad: GADInterstitial) {
    print("interstitialDidDismissScreen")
    interstitial = createAndLoadInterstitial()
}

この関数は GADInterstitialDelegate を継承していれば勝手にコールされる関数になります
呼び出されない場合は delete をちゃんと設定しているかなど確認してください

viewDidLoad でシーンに移動する

ここまでできたらシーン呼び出しましょう
その際にシーン側で定義した viewController を管理する変数にこの GameViewController を設定しましょう
こうすることでシーン側で GameViewController で定義した showAd 関数を呼び出すことができるようになります

override func viewDidLoad() {
    super.viewDidLoad()
    // 広告の初期化
    interstitial = createAndLoadInterstitial()

    if let view = self.view as! SKView? {
        if let scene = FirstScene(fileNamed: "FirstScene") {
            scene.scaleMode = .aspectFill
            // ここで GameViewController をセットする
            scene.viewController = self
            view.presentScene(scene)
        }
        view.ignoresSiblingOrder = true
        view.showsFPS = true
        view.showsNodeCount = true
    }
}

シーンファイルから呼び出す

ではシーンファイル側から広告を呼び出してみましょう
.sks ファイルにはラベルとボタン用の SKSpriteNode を 1 つ配置しました
あとは touchDown されたときに showAd をコールすれば広告が表示されます

import SpriteKit

class FirstScene: SKScene {

    // show ボタン
    var show = SKSpriteNode()
    var viewController: GameViewController!

    override func didMove(to view: SKView) {
        // show ボタンの初期化
        show = self.childNode(withName: "show") as! SKSpriteNode
    }

    func touchDown(atPoint pos : CGPoint) {
        if let node = atPoint(pos) as? SKSpriteNode {
            if(node == show){
                if let _ = self.view {
                    viewController.showAd()
                }
            }
        }
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for t in touches { self.touchDown(atPoint: t.location(in: self)) }
    }
}

動作確認

こんな感じで表示されれば OK です
spritekit_with_admob.gif

今回の場合非表示ボタンを押した後に再度インタースティシャル広告を生成しているので何度押しても表示されます
もし再生成していない場合は Ad wasn't ready となり広告も表示されません

最後に

SpriteKit + Admob (Interstitial Ad) をやってみました
バナービューの場合は storyboard を使って GADBannerView を生成するだけですが、ずっと表示されてしまうという問題もありインタースティシャル広告を使ってみました

ポイントは UIViewController 側で生成した広告をシーン側で呼び出す部分かなと思います
だったら初めからシーン側で広告も生成すればいいじゃんと思いますが、Admob の広告は基本的に View なのでシーン側で表示するとなるといろいろと大変です
あとはルールと言うか役割的な話で View はちゃんと UIViewController 側で表示したほうが良いです

参考サイト

0 件のコメント:

コメントを投稿