Search code examples
swiftsprite-kitiad

iAd interstitial presentation is delayed


I have made a game using Swift and Sprite Kit which loads an iAd interstitial when the player dies. However, the ad is sometimes delayed and therefore pops up during gameplay when the game is restarted. Is there any way to solve this? I call the iAd interstitial from my GameScene using:

NSNotificationCenter.defaultCenter().postNotificationName("showInterstitialAd", object: nil)

GameViewController.swift

import UIKit  
import SpriteKit  
import iAd  

class GameViewController: UIViewController, ADBannerViewDelegate, ADInterstitialAdDelegate {

    var interstitialAd:ADInterstitialAd!
    var interstitialAdView: UIView = UIView()
    let transition = SKTransition.fadeWithDuration(1)

    var closeButton = UIButton.buttonWithType(UIButtonType.System) as! UIButton

    override func viewDidLoad() {
        super.viewDidLoad()

        closeButton.frame = CGRectMake(10, 10, 20, 20)
        closeButton.layer.cornerRadius = 10
        closeButton.setTitle("x", forState: .Normal)
        closeButton.setTitleColor(UIColor.blackColor(), forState: .Normal)
        closeButton.backgroundColor = UIColor.whiteColor()
        closeButton.layer.borderColor = UIColor.blackColor().CGColor
        closeButton.layer.borderWidth = 1
        closeButton.addTarget(self, action: "close:", forControlEvents: UIControlEvents.TouchDown)

        //loadInterstitialAd()
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "loadInterstitialAd", name: "showInterstitialAd", object: nil)

        let scene = GameScene(size:CGSize(width: 2208, height: 1242))
        // Configure the view.
        let skView = self.view as! SKView
        skView.showsFPS = false
        skView.showsNodeCount = false

        /* Sprite Kit applies additional optimizations to improve rendering performance */
        skView.ignoresSiblingOrder = true

        /* Set the scale mode to scale to fit the window */
        scene.scaleMode = .AspectFit
        scene.anchorPoint = CGPoint(x: 0, y: 0)

        skView.presentScene(scene, transition: transition)
    }

    func close(sender: UIButton) {
        closeButton.removeFromSuperview()
        interstitialAdView.removeFromSuperview()
        interstitialAd.delegate = nil
    }

    func loadInterstitialAd() {
        interstitialAd = ADInterstitialAd()
        interstitialAd.delegate = self
    }

    func interstitialAdWillLoad(interstitialAd: ADInterstitialAd!) {
    }

    func interstitialAdDidLoad(interstitialAd: ADInterstitialAd!) {
        interstitialAd.delegate = self
        interstitialAdView = UIView()
        interstitialAdView.frame = self.view.bounds
        view.addSubview(interstitialAdView)
        view.addSubview(closeButton)
        interstitialAd.presentInView(interstitialAdView)
        UIViewController.prepareInterstitialAds()
    }

    func interstitialAdActionDidFinish(interstitialAd: ADInterstitialAd!) {
        closeButton.removeFromSuperview()
        interstitialAdView.removeFromSuperview()
    }

    func interstitialAdActionShouldBegin(interstitialAd: ADInterstitialAd!, willLeaveApplication willLeave: Bool) -> Bool {
        return true
    }

    func interstitialAd(interstitialAd: ADInterstitialAd!, didFailWithError error: NSError!) {
        interstitialAdView.removeFromSuperview()
        closeButton.removeFromSuperview()
        interstitialAd.delegate = nil
    }

    func interstitialAdDidUnload(interstitialAd: ADInterstitialAd!) {
        closeButton.removeFromSuperview()
        interstitialAdView.removeFromSuperview()
        interstitialAd.delegate = nil
    }

Solution

  • You've commented out //loadInterstitialAd() in your viewDidLoad. Uncomment this. You need to load the interstitial as early as possible so that when you do decide to present it it is fully loaded and ready to be displayed.

    Also, you're presenting your interstitial as soon as it loads in your func interstitialAdDidLoad(interstitialAd: ADInterstitialAd!). You should create a function or action to present your interstitial when you want it to, for example when the user takes a certain action or the game ends.

    Check my answer here. The interstitial is presented once a UIButton I've created, @IBAction func presentAdButton, is tapped.