Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display iAd banner in different SpriteKit Scenes

I made simple game with Swift and SpriteKit. Everything seems to work but I have a problem with my iAd Setup. I only want to show the ad banner in specific scenes (main menu and game over) not during the gameplay. My iAd setup works but only if it is displayed all the time. My last attempt to fix it was with the NSNotificationCenter method. I have done it as I have seen it in other question/answers here but the app crashes immediately after launch. Hope that someone could help me. Just let me know if you need more of my code. Thanks in advance.

GameViewController.swift

class GameViewController: UIViewController, ADBannerViewDelegate {

var adBannerView = ADBannerView(frame: CGRect.zeroRect)

override func viewDidLoad() {
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleNotification", name: "hideAd", object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleNotification", name: "showAd", object: nil)

    self.adBannerView.delegate = self
    self.adBannerView.hidden = true
    adBannerView.center = CGPoint(x: adBannerView.center.x, y: view.bounds.size.height - adBannerView.frame.size.height / 2)
    view.addSubview(adBannerView)

    if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
        // Configure the view.
        let skView = self.view as SKView

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

        var scene: SKScene = MainMenu(size: skView.bounds.size)
        scene.scaleMode = SKSceneScaleMode.AspectFill
        skView.presentScene(scene)
    }
}

func handleNotification(notification: NSNotification){
    if notification.name == "hideAd"{
        adBannerView.hidden = true
    }else if notification.name == "showAd"{
        adBannerView.hidden = false
    }
}

//iAD Setup
func bannerViewWillLoadAd(banner: ADBannerView!) {
    println("Ad loads")
}

func bannerViewDidLoadAd(banner: ADBannerView!){
    println("Ad loaded")
    self.adBannerView.hidden = false
}

func bannerViewActionDidFinish(banner: ADBannerView!) {
    println("resume scene")
    let skView = self.view as SKView
    skView.paused = false
}

func bannerViewActionShouldBegin(banner: ADBannerView!, willLeaveApplication willLeave: Bool) -> Bool {
    println("pause scene")
    let skView = self.view as SKView
    skView.paused = true
    return true
}

func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
    println("Failed to load ad")
    self.adBannerView.hidden = true
}   more code.... 

MainMenu.swift

class MainMenu: SKScene{

required init(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

override init(size:CGSize){
    super.init(size: size)

    NSNotificationCenter.defaultCenter().postNotificationName("showAd", object: nil)
more code...
like image 805
PatrickDotStar Avatar asked Jan 06 '15 22:01

PatrickDotStar


2 Answers

This works for me

In my view controller I have this code:

// Banner Ad

var SH = UIScreen.mainScreen().bounds.height
let transition = SKTransition.fadeWithDuration(1) 
var UIiAd: ADBannerView = ADBannerView()

override func viewWillAppear(animated: Bool) {
    var BV = UIiAd.bounds.height
    UIiAd.delegate = self
    UIiAd.frame = CGRectMake(0, SH + BV, 0, 0)
    self.view.addSubview(UIiAd)
}

override func viewWillDisappear(animated: Bool) {
    UIiAd.delegate = nil
    UIiAd.removeFromSuperview()
}

func bannerViewDidLoadAd(banner: ADBannerView!) {
    var BV = UIiAd.bounds.height
    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationDuration(1) // Time it takes the animation to complete
    UIiAd.alpha = 1 // Fade in the animation
    UIView.commitAnimations()
}

func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationDuration(1)
    UIiAd.alpha = 0
    UIView.commitAnimations()
}

func showBannerAd() {
    UIiAd.hidden = false
    var BV = UIiAd.bounds.height

    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationDuration(1) // Time it takes the animation to complete
    UIiAd.frame = CGRectMake(0, SH - BV, 0, 0) // End position of the animation
    UIView.commitAnimations()
}

func hideBannerAd() {
    UIiAd.hidden = true
    var BV = UIiAd.bounds.height

    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationDuration(1) // Time it takes the animation to complete
    UIiAd.frame = CGRectMake(0, SH + BV, 0, 0) // End position of the animation
    UIView.commitAnimations()
}

override func viewDidLoad() {
    super.viewDidLoad()
    self.UIiAd.hidden = true
    self.UIiAd.alpha = 0

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "hideBannerAd", name: "hideadsID", object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "showBannerAd", name: "showadsID", object: nil)


    let scene = GameScene()
    // 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.5, y: 0.5)
    scene.size = skView.bounds.size
    skView.presentScene(scene, transition: transition)
}

To display it in the scene I want (for me it's the GameOver scene) I did this:

override func didMoveToView(view: SKView) {

    showAds()
    // Rest of your code here...
}

func showAds(){
    NSNotificationCenter.defaultCenter().postNotificationName("showadsID", object: nil)
}

Basically this code creates a banner off the scene, and when the banner is loaded and the scene gets called, it slides up from the bottom. When you switch scenes, it offsets it again and when you come back to that scene, it slides up from the bottom again. If the banner doesn't load, it's off screen so no worries about it showing a white bar. Also, it sets the alpha to 0 if it doesn't load just in case (makes it invisible). Hope this helps.

like image 65
riverhawk Avatar answered Nov 14 '22 22:11

riverhawk


I USE THIS TO PRESENT THE iAd Banner in subview

var vc = self.view?.window?.rootViewController vc?.view.addSubview(adView!)

When I want to hide it when in the game (because iAd reduce FPS) I call

adView!.removeFromSuperview()

When the user finished the Game just add

         var vc = self.view?.window?.rootViewController
        vc?.view.addSubview(adView!)

to show the iAd banner again

BUT YOU NEED TO IMPLEMENT THIS CODE IN GameViewController

class GameViewController: ADBannerViewDelegate (you needed this too) also don't forget to import iAd at the top of gameviewcontroller also import iAd framework to the project

override func viewDidLoad() {
    self.ShowAd()

//Have this in view didLoad too

     func ShowAd() {
        super.viewDidLoad()
        adView = ADBannerView(adType: ADAdType.Banner)
        adView!.delegate = self

    }
    func bannerViewDidLoadAd(banner: ADBannerView!) {
        self.view.addSubview(adView!)
        self.view.layoutIfNeeded()
        println("Pass")
    }

    func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
        adView!.removeFromSuperview()
        /*var alert = UIAlertController(title: "iAd Message", message:
            "iAd Fail To Load", preferredStyle: UIAlertControllerStyle.Alert)

        self.presentViewController(alert, animated: false, completion: nil)

        alert.addAction(UIAlertAction(title: "dismiss", style: UIAlertActionStyle.Default,
            handler: nil))
        self.view.layoutIfNeeded()*/
        println("fail")
    }
like image 20
user4376578 Avatar answered Nov 14 '22 21:11

user4376578