Monday, February 9, 2015

How to implement a space shooter with SpriteKit and SWIFT - Part 7: iAd integration

Adding iAd integration




Welcome to part 7 of my swift programming tutorial. In the previous parts we've created sprites, added movement, enemies with a follow behaviour, bullets & shooting, a HUD, collision detection, sound & particle effects and a global leaderboard using Game Center. Today I'll show how to integrate the Apple Advertising Framework iAD:
  • Enable iAd in iTunesConnect
  • Add a Banner Ad (at the bottom of the screen)
  • Add a Fullscreen Ad (after game over)


Tutorial Overview:

  • Part 1: Initial project setup, sprite creation and movement using SKAction and SKConstraint
  • Part 2: Adding enemies, bullets and shooting with SKAction and SKConstraint
  • Part 3: Adding a HUD with SKLabelNode and SKSpriteNode
  • Part 4: Adding basic game logic and collision detection
  • Part 5: Adding particles and sound 
  • Part 6: GameCenter integration


Let's start:


1. Enable iAD support in iTunes Connect

You need a paid Apple Developer Account to execute the next steps. 

Open iTunes Connect and navigate to the Agreements, Tax and Banking section:


Request an iAd Agreement:

 

2. Add a Banner Ad

In this section I'll show how to add a banner add at the bottom of the screen. As a starting point you can download the code from part 6 here.


Import the iAd framework and implement the ADBannerViewDelegate protocol:

import iAd

class GameViewController: UIViewController, ADBannerViewDelegate, GKGameCenterControllerDelegate, GameSceneDelegate {

Add two properties to GameViewController to keep a reference to the banner object and the visibility state:


// Properties for Banner Ad
var iAdBanner = ADBannerView()

var bannerVisible = false

Add the code to initialise the banner at the end of viewDidAppear:


override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
        
    ...
        
        
    // Prepare banner Ad
    iAdBanner.frame = CGRectMake(0, self.view.frame.size.height, self.view.frame.width, 50)
    iAdBanner.delegate = self
    bannerVisible = false
        

}

Implement the protocol method bannerViewDidLoadAd to move the banner on the screen, if an ad is loaded:


// Show banner, if Ad is successfully loaded.
func bannerViewDidLoadAd(banner: ADBannerView!) {
    if(bannerVisible == false) {
            
        // Add banner Ad to the view
        if(iAdBanner.superview == nil) {
            self.view.addSubview(iAdBanner)
        }
            
        // Move banner into visible screen frame:
        UIView.beginAnimations("iAdBannerShow", context: nil)
        banner.frame = CGRectOffset(banner.frame, 0, -banner.frame.size.height)
        UIView.commitAnimations()
            
        bannerVisible = true
    }

}

Implement the protocol method bannerView to remove the banner from screen, if an ad is not available:


// Hide banner, if Ad is not loaded.
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
    if(bannerVisible == true) {
        // Move banner below screen frame:
        UIView.beginAnimations("iAdBannerHide", context: nil)
        banner.frame = CGRectOffset(banner.frame, 0, banner.frame.size.height)
        UIView.commitAnimations()
        bannerVisible = false
    }

}


3. Add a Fullscreen Ad


Add this code to prepare a Fullscreen Ad at the end of viewDidAppear:


override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
        
    ...
        
    // Prepare fullscreen Ad
    UIViewController.prepareInterstitialAds()        

}



Add a new method openAds to show a Action Sheet where the player can chose to open the Ad or play again:


// Open a fullscreen Ad
func openAds(sender: AnyObject) {
    // Create an alert
    var alert = UIAlertController(title: "", message: "Play again?", preferredStyle: UIAlertControllerStyle.Alert)
        
    // Play again option
    alert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.Default)  { _ in
        self.scene!.gameOver = false
        })
        
    // Show fullscreen Ad option
    alert.addAction(UIAlertAction(title: "Watch Ad", style: UIAlertActionStyle.Default)  { _ in
        self.interstitialPresentationPolicy = ADInterstitialPresentationPolicy.Manual
        self.requestInterstitialAdPresentation()
        self.scene!.gameOver = false
    })
        
    self.presentViewController(alert, animated: true, completion: nil)
}



Add the call of the action sheet method in gameOver and gameCenterViewControllerDidFinish:

// Show game center leaderboard
func gameOver() {
        
        ...
        
    // Show leaderboard
    if GKLocalPlayer.localPlayer().authenticated == true {
        self.presentViewController(gcViewController, animated: true, completion: {
        })
    } else {
        // Show fullscreen Ad
        self.openAds(self)
    }

}



// Continue the game after GameCenter is closed
func gameCenterViewControllerDidFinish(gameCenterViewController: GKGameCenterViewController!) {
    gameCenterViewController.dismissViewControllerAnimated(true, completion: nil)
        
    // Show fullscreen Ad
    openAds(self)
}






That's all for today. You can download the code from GitHub: Part 7 or the latest version

I've submitted this version to the Apple AppStore. In one of my next posts I'll show how to implement social media integration. If you want to get an idea what is coming: 
A more sophisticated game based on this tutorial series is available in the AppStore: 
Cheers, 
Stefan


4 comments:

  1. game center tutorial is dead

    ReplyDelete
  2. How did you create the explosion particle of the enemy ship? Where can I download?

    ReplyDelete
    Replies
    1. I've created an SKS file in XCode and played around with the values till I've got a nice explosion. The details are described in this tutorial: http://stefansdevplayground.blogspot.de/2014/12/how-to-implement-space-shooter-with.html

      Delete
  3. That's nice! But how to call them outside of the gameViewController? In the game over scene for example?

    ReplyDelete